//===--- PrintASTTests.cpp ----------------------------------------- C++-*-===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// #include "AST.h" #include "Annotations.h" #include "Protocol.h" #include "SourceCode.h" #include "TestTU.h" #include "clang/AST/RecursiveASTVisitor.h" #include "gmock/gmock.h" #include "gtest/gtest-param-test.h" #include "gtest/gtest.h" namespace clang { namespace clangd { namespace { using ::testing::ElementsAreArray; struct Case { const char *AnnotatedCode; std::vector Expected; }; class ASTUtils : public ::testing::Test, public ::testing::WithParamInterface {}; TEST_P(ASTUtils, PrintTemplateArgs) { auto Pair = GetParam(); Annotations Test(Pair.AnnotatedCode); auto AST = TestTU::withCode(Test.code()).build(); struct Visitor : RecursiveASTVisitor { Visitor(std::vector Points) : Points(std::move(Points)) {} bool VisitNamedDecl(const NamedDecl *ND) { if (TemplateArgsAtPoints.size() == Points.size()) return true; auto Pos = sourceLocToPosition(ND->getASTContext().getSourceManager(), ND->getLocation()); if (Pos != Points[TemplateArgsAtPoints.size()]) return true; TemplateArgsAtPoints.push_back(printTemplateSpecializationArgs(*ND)); return true; } std::vector TemplateArgsAtPoints; const std::vector Points; }; Visitor V(Test.points()); V.TraverseDecl(AST.getASTContext().getTranslationUnitDecl()); EXPECT_THAT(V.TemplateArgsAtPoints, ElementsAreArray(Pair.Expected)); } INSTANTIATE_TEST_CASE_P(ASTUtilsTests, ASTUtils, ::testing::ValuesIn(std::vector({ { R"cpp( template class Bar {}; template <> class ^Bar {};)cpp", {""}}, { R"cpp( template class Bar {}; template class Z, int Q> struct Foo {}; template struct ^Foo; template struct ^Foo {};)cpp", {"", ""}}, { R"cpp( template void Foz() {}; template <> void ^Foz<3, 5, 8>() {};)cpp", {"<3, 5, 8>"}}, { R"cpp( template class Bar {}; template