Add error reporting when looking up types by demangled name.

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

View File

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

View File

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

View File

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

View File

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

View File

@@ -21,7 +21,6 @@
#include "swift/Runtime/Unreachable.h"
#include <atomic>
#include <cstdarg>
#include <cstdio>
#include <functional>
#include <stdint.h>
@@ -248,39 +247,6 @@ std::atomic<const void *> _swift_debug_metadataAllocationBacktraceList;
SWIFT_RUNTIME_STDLIB_SPI
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
}

View File

@@ -16,8 +16,47 @@
#ifndef SWIFT_RUNTIME_PORTABILITY_H
#define SWIFT_RUNTIME_PORTABILITY_H
#include <cstdarg>
#include <cstddef>
#include <cstdio>
#include <cstdlib>
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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@@ -165,15 +165,16 @@ ProtocolConformanceDescriptor::getWitnessTable(const Metadata *type) const {
llvm::SmallVector<const void *, 8> conditionalArgs;
if (hasConditionalRequirements()) {
SubstGenericParametersFromMetadata substitutions(type);
bool failed =
_checkGenericRequirements(getConditionalRequirements(), conditionalArgs,
auto error = _checkGenericRequirements(
getConditionalRequirements(), conditionalArgs,
[&substitutions](unsigned depth, unsigned index) {
return substitutions.getMetadata(depth, index);
},
[&substitutions](const Metadata *type, unsigned index) {
return substitutions.getWitnessTable(type, index);
});
if (failed) return nullptr;
if (error)
return nullptr;
}
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::SmallVectorImpl<const void *> &extraArguments,
SubstGenericParameterFn substGenericParam,
SubstDependentWitnessTableFn substWitnessTable) {
for (const auto &req : requirements) {
// 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.
const Metadata *subjectType =
swift_getTypeByMangledName(MetadataState::Abstract,
req.getParam(),
extraArguments.data(),
substGenericParam, substWitnessTable).getMetadata();
if (!subjectType)
return true;
auto result = swift_getTypeByMangledName(
MetadataState::Abstract, req.getParam(), extraArguments.data(),
substGenericParam, substWitnessTable);
if (result.getError())
return *result.getError();
const Metadata *subjectType = result.getType().getMetadata();
// Check the requirement.
switch (req.getKind()) {
case GenericRequirementKind::Protocol: {
const WitnessTable *witnessTable = nullptr;
if (!_conformsToProtocol(nullptr, subjectType, req.getProtocol(),
&witnessTable))
return true;
&witnessTable)) {
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 (req.getProtocol().needsWitnessTable()) {
@@ -679,17 +685,19 @@ bool swift::_checkGenericRequirements(
case GenericRequirementKind::SameType: {
// Demangle the second type under the given substitutions.
auto otherType =
swift_getTypeByMangledName(MetadataState::Abstract,
req.getMangledTypeName(),
extraArguments.data(),
substGenericParam, substWitnessTable).getMetadata();
if (!otherType) return true;
auto result = swift_getTypeByMangledName(
MetadataState::Abstract, req.getMangledTypeName(),
extraArguments.data(), substGenericParam, substWitnessTable);
if (result.getError())
return *result.getError();
auto otherType = result.getType().getMetadata();
assert(!req.getFlags().hasExtraArgument());
// 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;
}
@@ -698,22 +706,24 @@ bool swift::_checkGenericRequirements(
switch (req.getLayout()) {
case GenericRequirementLayoutKind::Class:
if (!subjectType->satisfiesClassConstraint())
return true;
return TypeLookupError(
"subject type %s does not satisfy class constraint",
req.getParam());
continue;
}
// Unknown layout.
return true;
return TypeLookupError("unknown layout kind %u", req.getLayout());
}
case GenericRequirementKind::BaseClass: {
// Demangle the base type under the given substitutions.
auto baseType =
swift_getTypeByMangledName(MetadataState::Abstract,
req.getMangledTypeName(),
extraArguments.data(),
substGenericParam, substWitnessTable).getMetadata();
if (!baseType) return true;
auto result = swift_getTypeByMangledName(
MetadataState::Abstract, req.getMangledTypeName(),
extraArguments.data(), substGenericParam, substWitnessTable);
if (result.getError())
return *result.getError();
auto baseType = result.getType().getMetadata();
// If the type which is constrained to a base class is an existential
// type, and if that existential type includes a superclass constraint,
@@ -725,7 +735,8 @@ bool swift::_checkGenericRequirements(
}
if (!isSubclass(subjectType, baseType))
return true;
return TypeLookupError("%s is not subclass of %s", req.getParam(),
req.getMangledTypeName());
continue;
}
@@ -737,11 +748,12 @@ bool swift::_checkGenericRequirements(
}
// Unknown generic requirement kind.
return true;
return TypeLookupError("unknown generic requirement kind %u",
req.getKind());
}
// Success!
return false;
return llvm::None;
}
const Metadata *swift::findConformingSuperclass(

View File

@@ -400,9 +400,8 @@ getFieldAt(const Metadata *base, unsigned index) {
auto typeName = field.getMangledTypeName();
SubstGenericParametersFromMetadata substitutions(base);
auto typeInfo = swift_getTypeByMangledName(MetadataState::Complete,
typeName,
substitutions.getGenericArgs(),
auto result = swift_getTypeByMangledName(
MetadataState::Complete, typeName, substitutions.getGenericArgs(),
[&substitutions](unsigned depth, unsigned index) {
return substitutions.getMetadata(depth, index);
},
@@ -412,15 +411,22 @@ getFieldAt(const Metadata *base, unsigned index) {
// If demangling the type failed, pretend it's an empty type instead with
// a log message.
if (!typeInfo.getMetadata()) {
TypeInfo typeInfo;
if (result.isError()) {
typeInfo = TypeInfo({&METADATA_SYM(EMPTY_TUPLE_MANGLING),
MetadataState::Complete}, {});
auto *error = result.getError();
char *str = error->copyErrorString();
missing_reflection_metadata_warning(
"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",
(int)name.size(), name.data(),
(int)typeName.size(), typeName.data());
(int)name.size(), name.data(), (int)typeName.size(), typeName.data(),
str);
error->freeErrorString(str);
} else {
typeInfo = result.getType();
}
auto fieldType = FieldType(typeInfo.getMetadata());

View File

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

View File

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

View File

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

View File

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