From 13a8cbef6ee6d0fe158764cd776b818ce9712bbf Mon Sep 17 00:00:00 2001 From: ykiko Date: Sat, 7 Sep 2024 17:38:39 +0800 Subject: [PATCH] Resolver now can handle inner template class! --- src/AST/Resolver.cpp | 15 +++++++- tests/Resolver.cpp | 82 +++++++++++++++++++++++++++++++++++++++++++- 2 files changed, 95 insertions(+), 2 deletions(-) diff --git a/src/AST/Resolver.cpp b/src/AST/Resolver.cpp index c6f475eb..b39457fe 100644 --- a/src/AST/Resolver.cpp +++ b/src/AST/Resolver.cpp @@ -92,6 +92,13 @@ bool DependentNameResolver::lookup(llvm::SmallVector& result, TD = TST->getTemplateName().getAsTemplateDecl(); args = TST->template_arguments(); } else if(auto DTST = type->getAs()) { + if(lookup(result, DTST->getQualifier(), DTST->getIdentifier()) && result.size() == 1) { + TD = llvm::dyn_cast(result.front()); + args = DTST->template_arguments(); + result.clear(); + } else { + return false; + } } if(auto CTD = llvm::dyn_cast(TD)) { @@ -143,7 +150,8 @@ bool DependentNameResolver::lookup(llvm::SmallVector& result, // NOTE: takeSugared will take the ownership of the list auto list = info.takeSugared(); frames.emplace_back(partial, list->asArray()); - delete list; + // FIXME: should we delete the list? + // delete list; return true; } @@ -162,7 +170,10 @@ static bool isalias(clang::QualType type) { return false; } else if(auto DNT = type->getAs()) { return isalias(clang::QualType(DNT->getQualifier()->getAsType(), 0)); + } else if(auto LVRT = type->getAs()) { + return isalias(LVRT->getPointeeType()); } else { + type.dump(); std::terminate(); } } @@ -178,6 +189,8 @@ clang::QualType DependentNameResolver::dealias(clang::QualType type) { auto type = dealias(clang::QualType(DNT->getQualifier()->getAsType(), 0)); auto prefix = clang::NestedNameSpecifier::Create(context, nullptr, false, type.getTypePtr()); return context.getDependentNameType(DNT->getKeyword(), prefix, DNT->getIdentifier()); + } else if(auto LVRT = type->getAs()) { + return context.getLValueReferenceType(dealias(LVRT->getPointeeType())); } else { std::terminate(); } diff --git a/tests/Resolver.cpp b/tests/Resolver.cpp index 95733da5..837ab390 100644 --- a/tests/Resolver.cpp +++ b/tests/Resolver.cpp @@ -9,7 +9,7 @@ std::vector compileArgs = { "clang++", "-std=c++20", "main.cpp", - "-resource-dir=../build/lib/clang/20", + "-resource-dir=/home/ykiko/C++/clice2/build/lib/clang/20", }; struct Visitor : public clang::RecursiveASTVisitor { @@ -252,5 +252,85 @@ struct test { ASSERT_EQ(Y->getDecl()->getName(), "Y"); } +TEST(DependentNameResolver, dependent_member_class_template) { + const char* code = R"( +template +struct type_list {}; + +template +struct A { + template + struct B { + using type = type_list; + }; +}; + +template +struct test { + using result = typename A::template B::type; +}; +)"; + + Visitor visitor(code); + clang::QualType result = visitor.test(); + + auto TST = result->getAs(); + ASSERT_TRUE(TST); + ASSERT_EQ(TST->getTemplateName().getAsTemplateDecl()->getName(), "type_list"); + + auto args = TST->template_arguments(); + ASSERT_EQ(args.size(), 2); + + auto X = llvm::dyn_cast(args[0].getAsType()); + ASSERT_TRUE(X); + ASSERT_EQ(X->getDecl()->getName(), "X"); + + auto Y = llvm::dyn_cast(args[1].getAsType()); + ASSERT_TRUE(Y); + ASSERT_EQ(Y->getDecl()->getName(), "Y"); +} + +TEST(DependentNameResolver, dependent_partial_name) { + const char* code = R"( +template +struct type_list {}; + +template +struct A {}; + +template +struct B {}; + +template typename HKT> +struct B> { + using type = type_list; +}; + +template +struct test { + using result = typename B>::type; +}; +)"; + + Visitor visitor(code); + clang::QualType result = visitor.test(); + result->dump(); +} + +// TEST(DependentNameResolver, std_vector) { +// const char* code = R"( +// #include +// +// template +// struct test { +// using result = typename std::vector>::reference; +// }; +//)"; +// +// Visitor visitor(code); +// clang::QualType result = visitor.test(); +// result->dump(); +// } + } // namespace