mirror of
https://github.com/apple/swift.git
synced 2025-12-21 12:14:44 +01:00
Today ParenType is used: 1. As the type of ParenExpr 2. As the payload type of an unlabeled single associated value enum case (and the type of ParenPattern). 3. As the type for an `(X)` TypeRepr For 1, this leads to some odd behavior, e.g the type of `(5.0 * 5).squareRoot()` is `(Double)`. For 2, we should be checking the arity of the enum case constructor parameters and the presence of ParenPattern respectively. Eventually we ought to consider replacing Paren/TuplePattern with a PatternList node, similar to ArgumentList. 3 is one case where it could be argued that there's some utility in preserving the sugar of the type that the user wrote. However it's really not clear to me that this is particularly desirable since a bunch of diagnostic logic is already stripping ParenTypes. In cases where we care about how the type was written in source, we really ought to be consulting the TypeRepr.
311 lines
11 KiB
C++
311 lines
11 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/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 TypeDecl;
|
|
|
|
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());
|
|
|
|
/// An implementation of MetadataReader's BuilderType concept that
|
|
/// just finds and builds things in the AST.
|
|
class ASTBuilder {
|
|
ASTContext &Ctx;
|
|
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) {
|
|
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; }
|
|
DeclContext *getNotionalDC();
|
|
|
|
Demangle::NodeFactory &getNodeFactory() { return Factory; }
|
|
|
|
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);
|
|
|
|
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 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);
|
|
|
|
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);
|
|
};
|
|
|
|
SWIFT_END_INLINE_NAMESPACE
|
|
} // namespace Demangle
|
|
|
|
} // namespace swift
|
|
|
|
#endif // SWIFT_AST_ASTDEMANGLER_H
|