Skip to content

Commit ae920a4

Browse files
author
Enrico Granata
committed
Changes required for ReconstructType to be able to reconstruct types from qualified archetype manglings
1 parent 74d44b7 commit ae920a4

File tree

1 file changed

+142
-0
lines changed

1 file changed

+142
-0
lines changed

lib/IDE/ReconstructType.cpp

Lines changed: 142 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -77,6 +77,64 @@ static std::string stringWithFormat(const std::string fmt_str, ...) {
7777
return std::string(formatted.get());
7878
}
7979

80+
static swift::TypeBase*
81+
GetTemplateArgument (swift::TypeBase* type,
82+
size_t arg_idx)
83+
{
84+
if (type)
85+
{
86+
swift::CanType swift_can_type = type->getDesugaredType()->getCanonicalType();
87+
88+
const swift::TypeKind type_kind = swift_can_type->getKind();
89+
switch (type_kind)
90+
{
91+
case swift::TypeKind::UnboundGeneric:
92+
{
93+
swift::UnboundGenericType *unbound_generic_type = swift_can_type->getAs<swift::UnboundGenericType>();
94+
if (!unbound_generic_type)
95+
break;
96+
swift::NominalTypeDecl *nominal_type_decl = unbound_generic_type->getDecl();
97+
if (!nominal_type_decl)
98+
break;
99+
swift::GenericParamList *generic_param_list = nominal_type_decl->getGenericParams();
100+
if (!generic_param_list)
101+
break;
102+
if (arg_idx >= generic_param_list->getAllArchetypes().size())
103+
break;
104+
return generic_param_list->getAllArchetypes()[arg_idx];
105+
}
106+
break;
107+
case swift::TypeKind::BoundGenericClass:
108+
case swift::TypeKind::BoundGenericStruct:
109+
case swift::TypeKind::BoundGenericEnum:
110+
{
111+
swift::BoundGenericType *bound_generic_type = swift_can_type->getAs<swift::BoundGenericType>();
112+
if (!bound_generic_type)
113+
break;
114+
const llvm::ArrayRef<swift::Substitution>& substitutions = bound_generic_type->getSubstitutions(nullptr,nullptr);
115+
if (arg_idx >= substitutions.size())
116+
break;
117+
const swift::Substitution& substitution = substitutions[arg_idx];
118+
return substitution.getReplacement().getPointer();
119+
}
120+
case swift::TypeKind::PolymorphicFunction:
121+
{
122+
swift::PolymorphicFunctionType *polymorhpic_func_type = swift_can_type->getAs<swift::PolymorphicFunctionType>();
123+
if (!polymorhpic_func_type)
124+
break;
125+
if (arg_idx >= polymorhpic_func_type->getGenericParameters().size())
126+
break;
127+
return polymorhpic_func_type->getGenericParameters()[arg_idx]->getArchetype();
128+
}
129+
break;
130+
default:
131+
break;
132+
}
133+
}
134+
135+
return nullptr;
136+
}
137+
80138
enum class MemberType : uint32_t {
81139
Invalid,
82140
BaseClass,
@@ -469,6 +527,30 @@ class DeclsLookupSource {
469527
return (this->operator bool()) && (_type == Type::Extension);
470528
}
471529

530+
swift::Type
531+
GetQualifiedArchetype (size_t index,
532+
swift::ASTContext* ast)
533+
{
534+
if (this->operator bool() && ast)
535+
{
536+
switch (_type)
537+
{
538+
case Type::Extension:
539+
{
540+
swift::TypeBase *type_ptr = _extension._decl->getType().getPointer();
541+
if (swift::MetatypeType *metatype_ptr = type_ptr->getAs<swift::MetatypeType>())
542+
type_ptr = metatype_ptr->getInstanceType().getPointer();
543+
swift::TypeBase *archetype = GetTemplateArgument(type_ptr, index);
544+
return swift::Type(archetype);
545+
}
546+
break;
547+
default:
548+
break;
549+
}
550+
}
551+
return swift::Type();
552+
}
553+
472554
private:
473555
Type _type;
474556

@@ -2239,6 +2321,66 @@ VisitNodeQualifiedArchetype (SwiftASTContext *ast,
22392321
const VisitNodeResult &generic_context, // set by GenericType case
22402322
Log *log)
22412323
{
2324+
if (cur_node->begin() != cur_node->end())
2325+
{
2326+
swift::Demangle::Node::iterator end = cur_node->end();
2327+
VisitNodeResult type_result;
2328+
uint64_t index = 0xFFFFFFFFFFFFFFFF;
2329+
for (swift::Demangle::Node::iterator pos = cur_node->begin(); pos != end; ++pos)
2330+
{
2331+
switch (pos->get()->getKind())
2332+
{
2333+
case swift::Demangle::Node::Kind::Number:
2334+
index = pos->get()->getIndex();
2335+
break;
2336+
case swift::Demangle::Node::Kind::DeclContext:
2337+
nodes.push_back(*pos);
2338+
VisitNode (ast, nodes, type_result, generic_context, log);
2339+
break;
2340+
default:
2341+
break;
2342+
}
2343+
}
2344+
if (index != 0xFFFFFFFFFFFFFFFF)
2345+
{
2346+
if (type_result._types.size() == 1 && type_result._decls.size() == 1)
2347+
{
2348+
// given a method defined as func ... (args) -> (ret) {...}
2349+
// the Swift type system represents it as
2350+
// (SomeTypeMoniker) -> (args) -> (ret), where SomeTypeMoniker is an appropriately crafted
2351+
// reference to the type that contains the method (e.g. for a struct, an @inout StructType)
2352+
// For a qualified archetype of a method, we do not care about the first-level function, but about
2353+
// the returned function, which is the thing whose archetypes we truly care to extract
2354+
// TODO: this might be a generally useful operation, but it requires a Decl as well as a type
2355+
// to be reliably performed, and as such we cannot just put it in CompilerType as of now
2356+
// (consider, func foo (@inout StructType) -> (Int) -> () vs struct StructType {func foo(Int) -> ()} to see why)
2357+
swift::TypeBase *type_ptr = type_result._types[0].getPointer();
2358+
swift::Decl* decl_ptr = type_result._decls[0];
2359+
// if this is a function...
2360+
if (type_ptr && type_ptr->is<swift::AnyFunctionType>())
2361+
{
2362+
// if this is defined in a type...
2363+
if (decl_ptr->getDeclContext()->isTypeContext())
2364+
{
2365+
// if I can get the function type from it
2366+
if (auto func_type = llvm::dyn_cast_or_null<swift::AnyFunctionType>(type_ptr))
2367+
{
2368+
// and it has a return type which is itself a function
2369+
auto return_func_type = llvm::dyn_cast_or_null<swift::AnyFunctionType>(func_type->getResult().getPointer());
2370+
if (return_func_type)
2371+
type_ptr = return_func_type; // then use IT as our source of archetypes
2372+
}
2373+
}
2374+
}
2375+
swift::TypeBase *arg_type = GetTemplateArgument(type_ptr, index);
2376+
result._types.push_back(swift::Type(arg_type));
2377+
}
2378+
else if (type_result._module.IsExtension())
2379+
{
2380+
result._types.push_back(type_result._module.GetQualifiedArchetype(index, ast));
2381+
}
2382+
}
2383+
}
22422384
}
22432385

22442386
static void

0 commit comments

Comments
 (0)