mirror of
https://github.com/apple/swift.git
synced 2025-12-14 20:36:38 +01:00
342 lines
13 KiB
C++
342 lines
13 KiB
C++
//===--- ASTDemangler.h - Swift AST symbol demangling -----------*- C++ -*-===//
|
|
//
|
|
// This source file is part of the Swift.org open source project
|
|
//
|
|
// Copyright (c) 2014 - 2017 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
|
|
//
|
|
//===----------------------------------------------------------------------===//
|
|
//
|
|
// Defines a builder concept for the TypeDecoder and MetadataReader which builds
|
|
// AST Types, and a utility function wrapper which takes a mangled string and
|
|
// feeds it through the TypeDecoder instance.
|
|
//
|
|
// The RemoteAST library defines a MetadataReader instance that uses this
|
|
// concept, together with some additional utilities.
|
|
//
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
#ifndef SWIFT_AST_ASTDEMANGLER_H
|
|
#define SWIFT_AST_ASTDEMANGLER_H
|
|
|
|
#include "swift/AST/ASTContext.h"
|
|
#include "swift/AST/Types.h"
|
|
#include "swift/Demangling/Demangler.h"
|
|
#include "swift/Demangling/NamespaceMacros.h"
|
|
#include "swift/Demangling/TypeDecoder.h"
|
|
#include "llvm/ADT/ArrayRef.h"
|
|
#include "llvm/ADT/StringRef.h"
|
|
#include <optional>
|
|
|
|
namespace swift {
|
|
|
|
class Decl;
|
|
class TypeDecl;
|
|
class DeclName;
|
|
|
|
namespace Demangle {
|
|
SWIFT_BEGIN_INLINE_NAMESPACE
|
|
|
|
Type getTypeForMangling(ASTContext &ctx,
|
|
llvm::StringRef mangling,
|
|
GenericSignature genericSig=GenericSignature());
|
|
|
|
TypeDecl *getTypeDeclForMangling(ASTContext &ctx,
|
|
llvm::StringRef mangling,
|
|
GenericSignature genericSig=GenericSignature());
|
|
|
|
TypeDecl *getTypeDeclForUSR(ASTContext &ctx,
|
|
llvm::StringRef usr,
|
|
GenericSignature genericSig=GenericSignature());
|
|
|
|
Decl *getDeclForUSR(ASTContext &ctx, llvm::StringRef usr,
|
|
GenericSignature genericSig = GenericSignature());
|
|
|
|
/// An implementation of MetadataReader's BuilderType concept that
|
|
/// just finds and builds things in the AST.
|
|
class ASTBuilder {
|
|
ASTContext &Ctx;
|
|
Mangle::ManglingFlavor ManglingFlavor;
|
|
Demangle::NodeFactory Factory;
|
|
|
|
/// The notional context in which we're writing and type-checking code.
|
|
/// Created lazily.
|
|
DeclContext *NotionalDC = nullptr;
|
|
|
|
/// The depth and index of each parameter pack in the current generic
|
|
/// signature. We need this because the mangling for a type parameter
|
|
/// doesn't record whether it is a pack or not; we find the correct
|
|
/// depth and index in this array, and use its pack-ness.
|
|
llvm::SmallVector<std::pair<unsigned, unsigned>, 2> ParameterPacks;
|
|
|
|
/// For saving and restoring generic parameters.
|
|
llvm::SmallVector<decltype(ParameterPacks), 2> ParameterPackStack;
|
|
|
|
/// The depth and index of each value parameter in the current generic
|
|
/// signature. We need this becasue the mangling for a type parameter
|
|
/// doesn't record whether it is a value or not; we find the correct
|
|
/// depth and index in this array, and use its value-ness.
|
|
llvm::SmallVector<std::tuple<std::pair<unsigned, unsigned>, Type>, 1> ValueParameters;
|
|
|
|
/// For saving and restoring generic parameters.
|
|
llvm::SmallVector<decltype(ValueParameters), 1> ValueParametersStack;
|
|
|
|
/// This builder doesn't perform "on the fly" substitutions, so we preserve
|
|
/// all pack expansions. We still need an active expansion stack though,
|
|
/// for the dummy implementation of these methods:
|
|
/// - beginPackExpansion()
|
|
/// - advancePackExpansion()
|
|
/// - createExpandedPackElement()
|
|
/// - endPackExpansion()
|
|
llvm::SmallVector<Type, 2> ActivePackExpansions;
|
|
|
|
public:
|
|
using BuiltType = swift::Type;
|
|
using BuiltTypeDecl = swift::GenericTypeDecl *; // nominal or type alias
|
|
using BuiltProtocolDecl = swift::ProtocolDecl *;
|
|
using BuiltGenericSignature = swift::GenericSignature;
|
|
using BuiltRequirement = swift::Requirement;
|
|
using BuiltInverseRequirement = swift::InverseRequirement;
|
|
using BuiltSubstitutionMap = swift::SubstitutionMap;
|
|
|
|
static constexpr bool needsToPrecomputeParentGenericContextShapes = false;
|
|
|
|
explicit ASTBuilder(ASTContext &ctx, GenericSignature genericSig) : Ctx(ctx) {
|
|
ManglingFlavor = ctx.LangOpts.hasFeature(Feature::Embedded)
|
|
? Mangle::ManglingFlavor::Embedded
|
|
: Mangle::ManglingFlavor::Default;
|
|
|
|
for (auto *paramTy : genericSig.getGenericParams()) {
|
|
if (paramTy->isParameterPack())
|
|
ParameterPacks.emplace_back(paramTy->getDepth(), paramTy->getIndex());
|
|
|
|
if (paramTy->isValue()) {
|
|
auto pair = std::make_pair(paramTy->getDepth(), paramTy->getIndex());
|
|
auto tuple = std::make_tuple(pair, paramTy->getValueType());
|
|
ValueParameters.emplace_back(tuple);
|
|
}
|
|
}
|
|
}
|
|
|
|
ASTContext &getASTContext() { return Ctx; }
|
|
Mangle::ManglingFlavor getManglingFlavor() { return ManglingFlavor; }
|
|
DeclContext *getNotionalDC();
|
|
|
|
Demangle::NodeFactory &getNodeFactory() { return Factory; }
|
|
|
|
/// Finds the \c Decl associated with the provided \p node.
|
|
/// Attempts to find a type declaration using \c createTypeDecl, if not found,
|
|
/// it performs a lookup for the declaration and returns the first declaration
|
|
/// for which \c isMatchingValueDecl returns true.
|
|
///
|
|
/// \note \p isMatchingValueDecl is not evaluated for type declarations, it's
|
|
/// only used to choose among lookup results when \c createTypeDecl fails.
|
|
Decl *
|
|
findDecl(NodePointer node,
|
|
llvm::function_ref<bool(const ValueDecl *)> isMatchingValueDecl);
|
|
|
|
Type decodeMangledType(NodePointer node, bool forRequirement = true);
|
|
Type createBuiltinType(StringRef builtinName, StringRef mangledName);
|
|
|
|
TypeDecl *createTypeDecl(NodePointer node);
|
|
|
|
GenericTypeDecl *createTypeDecl(StringRef mangledName, bool &typeAlias);
|
|
|
|
GenericTypeDecl *createTypeDecl(NodePointer node,
|
|
bool &typeAlias);
|
|
|
|
ProtocolDecl *createProtocolDecl(NodePointer node);
|
|
|
|
Type createNominalType(GenericTypeDecl *decl);
|
|
|
|
Type createNominalType(GenericTypeDecl *decl, Type parent);
|
|
|
|
Type createTypeAliasType(GenericTypeDecl *decl, Type parent);
|
|
|
|
Type createBoundGenericType(GenericTypeDecl *decl, ArrayRef<Type> args);
|
|
|
|
OpaqueTypeDecl *resolveOpaqueTypeDecl(NodePointer opaqueDescriptor);
|
|
|
|
Type resolveOpaqueType(NodePointer opaqueDescriptor,
|
|
ArrayRef<ArrayRef<Type>> args,
|
|
unsigned ordinal);
|
|
|
|
Type createBoundGenericType(GenericTypeDecl *decl, ArrayRef<Type> args,
|
|
Type parent);
|
|
|
|
Type createTupleType(ArrayRef<Type> eltTypes, ArrayRef<StringRef> labels);
|
|
|
|
Type createPackType(ArrayRef<Type> eltTypes);
|
|
|
|
Type createSILPackType(ArrayRef<Type> eltTypes, bool isElementAddress);
|
|
|
|
size_t beginPackExpansion(Type countType);
|
|
|
|
void advancePackExpansion(size_t index);
|
|
|
|
Type createExpandedPackElement(Type patternType);
|
|
|
|
void endPackExpansion();
|
|
|
|
Type createFunctionType(
|
|
ArrayRef<Demangle::FunctionParam<Type>> params,
|
|
Type output, FunctionTypeFlags flags, ExtendedFunctionTypeFlags extFlags,
|
|
FunctionMetadataDifferentiabilityKind diffKind, Type globalActor,
|
|
Type thrownError);
|
|
|
|
Type createImplFunctionType(
|
|
Demangle::ImplParameterConvention calleeConvention,
|
|
Demangle::ImplCoroutineKind coroutineKind,
|
|
ArrayRef<Demangle::ImplFunctionParam<Type>> params,
|
|
ArrayRef<Demangle::ImplFunctionYield<Type>> yields,
|
|
ArrayRef<Demangle::ImplFunctionResult<Type>> results,
|
|
std::optional<Demangle::ImplFunctionResult<Type>> errorResult,
|
|
ImplFunctionTypeFlags flags);
|
|
|
|
Type createProtocolCompositionType(ArrayRef<ProtocolDecl *> protocols,
|
|
Type superclass,
|
|
bool isClassBound,
|
|
bool forRequirement = true);
|
|
|
|
Type createProtocolTypeFromDecl(ProtocolDecl *protocol);
|
|
|
|
Type createConstrainedExistentialType(
|
|
Type base,
|
|
ArrayRef<BuiltRequirement> constraints,
|
|
ArrayRef<BuiltInverseRequirement> inverseRequirements);
|
|
|
|
Type createSymbolicExtendedExistentialType(NodePointer shapeNode,
|
|
ArrayRef<Type> genArgs);
|
|
|
|
Type createExistentialMetatypeType(
|
|
Type instance,
|
|
std::optional<Demangle::ImplMetatypeRepresentation> repr = std::nullopt);
|
|
|
|
Type createMetatypeType(
|
|
Type instance,
|
|
std::optional<Demangle::ImplMetatypeRepresentation> repr = std::nullopt);
|
|
|
|
void pushGenericParams(ArrayRef<std::pair<unsigned, unsigned>> parameterPacks);
|
|
void popGenericParams();
|
|
|
|
Type createGenericTypeParameterType(unsigned depth, unsigned index);
|
|
|
|
Type createDependentMemberType(StringRef member, Type base);
|
|
|
|
Type createDependentMemberType(StringRef member, Type base,
|
|
ProtocolDecl *protocol);
|
|
|
|
#define REF_STORAGE(Name, ...) \
|
|
Type create##Name##StorageType(Type base);
|
|
#include "swift/AST/ReferenceStorage.def"
|
|
|
|
Type createSILBoxType(Type base);
|
|
using BuiltSILBoxField = llvm::PointerIntPair<Type, 1>;
|
|
using BuiltSubstitution = std::pair<Type, Type>;
|
|
using BuiltLayoutConstraint = swift::LayoutConstraint;
|
|
Type createSILBoxTypeWithLayout(
|
|
ArrayRef<BuiltSILBoxField> Fields,
|
|
ArrayRef<BuiltSubstitution> Substitutions,
|
|
ArrayRef<BuiltRequirement> Requirements,
|
|
ArrayRef<BuiltInverseRequirement> inverseRequirements);
|
|
|
|
bool isExistential(Type type) {
|
|
return type->isExistentialType();
|
|
}
|
|
|
|
|
|
Type createObjCClassType(StringRef name);
|
|
|
|
Type createBoundGenericObjCClassType(StringRef name, ArrayRef<Type> args);
|
|
|
|
ProtocolDecl *createObjCProtocolDecl(StringRef name);
|
|
|
|
Type createDynamicSelfType(Type selfType);
|
|
|
|
Type createForeignClassType(StringRef mangledName);
|
|
|
|
Type getUnnamedForeignClassType();
|
|
|
|
Type getOpaqueType();
|
|
|
|
Type createOptionalType(Type base);
|
|
|
|
Type createArrayType(Type base);
|
|
|
|
Type createInlineArrayType(Type count, Type element);
|
|
|
|
Type createDictionaryType(Type key, Type value);
|
|
|
|
Type createIntegerType(intptr_t value);
|
|
|
|
Type createNegativeIntegerType(intptr_t value);
|
|
|
|
Type createBuiltinFixedArrayType(Type size, Type element);
|
|
|
|
BuiltGenericSignature
|
|
createGenericSignature(ArrayRef<BuiltType> params,
|
|
ArrayRef<BuiltRequirement> requirements);
|
|
|
|
BuiltSubstitutionMap createSubstitutionMap(BuiltGenericSignature sig,
|
|
ArrayRef<BuiltType> replacements);
|
|
|
|
Type subst(Type subject, const BuiltSubstitutionMap &Subs) const;
|
|
|
|
LayoutConstraint getLayoutConstraint(LayoutConstraintKind kind);
|
|
LayoutConstraint getLayoutConstraintWithSizeAlign(LayoutConstraintKind kind,
|
|
unsigned size,
|
|
unsigned alignment);
|
|
|
|
InverseRequirement createInverseRequirement(
|
|
Type subject, InvertibleProtocolKind kind);
|
|
|
|
private:
|
|
bool validateParentType(TypeDecl *decl, Type parent);
|
|
CanGenericSignature demangleGenericSignature(
|
|
NominalTypeDecl *nominalDecl,
|
|
NodePointer node);
|
|
DeclContext *findDeclContext(NodePointer node);
|
|
|
|
/// Find all the ModuleDecls that correspond to a module node's identifier.
|
|
/// The module name encoded in the node is either the module's real or ABI
|
|
/// name. Multiple modules can share the same name. This function returns
|
|
/// all modules that contain that name.
|
|
llvm::ArrayRef<ModuleDecl *> findPotentialModules(NodePointer node,
|
|
ModuleDecl *&scratch);
|
|
|
|
Demangle::NodePointer findModuleNode(NodePointer node);
|
|
|
|
enum class ForeignModuleKind {
|
|
Imported,
|
|
SynthesizedByImporter
|
|
};
|
|
|
|
std::optional<ForeignModuleKind> getForeignModuleKind(NodePointer node);
|
|
|
|
GenericTypeDecl *findTypeDecl(DeclContext *dc,
|
|
Identifier name,
|
|
Identifier privateDiscriminator,
|
|
Demangle::Node::Kind kind);
|
|
GenericTypeDecl *findForeignTypeDecl(StringRef name,
|
|
StringRef relatedEntityKind,
|
|
ForeignModuleKind lookupKind,
|
|
Demangle::Node::Kind kind);
|
|
|
|
static GenericTypeDecl *getAcceptableTypeDeclCandidate(ValueDecl *decl,
|
|
Demangle::Node::Kind kind);
|
|
|
|
/// Returns an identifier with the given name, automatically removing any
|
|
/// surrounding backticks that are present for raw identifiers.
|
|
Identifier getIdentifier(StringRef name);
|
|
};
|
|
|
|
SWIFT_END_INLINE_NAMESPACE
|
|
} // namespace Demangle
|
|
|
|
} // namespace swift
|
|
|
|
#endif // SWIFT_AST_ASTDEMANGLER_H
|