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

@@ -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,
@@ -1245,8 +1314,9 @@ public:
return ProtocolDescriptorRef();
#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,24 +1333,25 @@ 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,
BuiltType parent) const {
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
// CF types are mangled as type aliases.
return createNominalType(typeAliasDecl, parent);
}
BuiltType createBoundGenericType(BuiltTypeDecl anyTypeDecl,
llvm::ArrayRef<BuiltType> genericArgs,
BuiltType parent) const {
TypeLookupErrorOr<BuiltType>
createBoundGenericType(BuiltTypeDecl anyTypeDecl,
llvm::ArrayRef<BuiltType> genericArgs,
BuiltType parent) const {
auto typeDecl = dyn_cast<TypeContextDescriptor>(anyTypeDecl);
if (!typeDecl) {
if (auto protocol = dyn_cast<ProtocolDescriptor>(anyTypeDecl))
@@ -1294,13 +1365,11 @@ 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();
if (!accessFunction) return BuiltType();
@@ -1308,8 +1377,8 @@ public:
return accessFunction(MetadataState::Abstract, allGenericArgsVec).Value;
}
BuiltType createBuiltinType(StringRef builtinName,
StringRef mangledName) const {
TypeLookupErrorOr<BuiltType> createBuiltinType(StringRef builtinName,
StringRef mangledName) const {
#define BUILTIN_TYPE(Symbol, _) \
if (mangledName.equals(#Symbol)) \
return &METADATA_SYM(Symbol).base;
@@ -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,8 +1465,9 @@ public:
return BuiltType();
}
BuiltType createTupleType(llvm::ArrayRef<BuiltType> elements,
std::string labels) const {
TypeLookupErrorOr<BuiltType>
createTupleType(llvm::ArrayRef<BuiltType> elements,
std::string labels) const {
auto flags = TupleTypeFlags().withNumElements(elements.size());
if (!labels.empty())
flags = flags.withNonConstantLabels(true);
@@ -1408,13 +1478,15 @@ 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,
BuiltProtocolDecl protocol) const {
TypeLookupErrorOr<BuiltType>
createDependentMemberType(StringRef name, BuiltType base,
BuiltProtocolDecl protocol) const {
#if SWIFT_OBJC_INTEROP
if (protocol.isObjC())
return BuiltType();
@@ -1438,14 +1510,14 @@ public:
*assocType).Value;
}
#define REF_STORAGE(Name, ...) \
BuiltType create##Name##StorageType(BuiltType base) { \
ReferenceOwnership.set##Name(); \
return base; \
#define REF_STORAGE(Name, ...) \
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,13 +1551,12 @@ public:
}
SWIFT_CC(swift)
static TypeInfo swift_getTypeByMangledNodeImpl(
MetadataRequest request,
Demangler &demangler,
Demangle::NodePointer node,
const void * const *origArgumentVector,
SubstGenericParameterFn substGenericParam,
SubstDependentWitnessTableFn substWitnessTable) {
static TypeLookupErrorOr<TypeInfo>
swift_getTypeByMangledNodeImpl(MetadataRequest request, Demangler &demangler,
Demangle::NodePointer node,
const void *const *origArgumentVector,
SubstGenericParameterFn substGenericParam,
SubstDependentWitnessTableFn substWitnessTable) {
// Simply call an accessor function if that's all we got.
if (node->getKind() == Node::Kind::AccessorFunctionReference) {
// The accessor function is passed the pointer to the original argument
@@ -1504,22 +1576,23 @@ 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),
builder.getReferenceOwnership()};
return TypeInfo{swift_checkMetadataState(request, type.getType()),
builder.getReferenceOwnership()};
}
SWIFT_CC(swift)
static TypeInfo swift_getTypeByMangledNameImpl(
MetadataRequest request,
StringRef typeName,
const void * const *origArgumentVector,
SubstGenericParameterFn substGenericParam,
SubstDependentWitnessTableFn substWitnessTable) {
static TypeLookupErrorOr<TypeInfo>
swift_getTypeByMangledNameImpl(MetadataRequest request, StringRef typeName,
const void *const *origArgumentVector,
SubstGenericParameterFn substGenericParam,
SubstDependentWitnessTableFn substWitnessTable) {
DemanglerForRuntimeTypeResolution<StackAllocatedDemangler<2048>> demangler;
NodePointer node;
@@ -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;
}