1 //===--- PrintASTTests.cpp ----------------------------------------- C++-*-===//
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
7 //===----------------------------------------------------------------------===//
10 #include "Annotations.h"
12 #include "SourceCode.h"
14 #include "clang/AST/RecursiveASTVisitor.h"
15 #include "gmock/gmock.h"
16 #include "gtest/gtest.h"
22 using ::testing::ElementsAreArray
;
25 const char *AnnotatedCode
;
26 std::vector
<const char *> Expected
;
28 class ASTUtils
: public ::testing::Test
,
29 public ::testing::WithParamInterface
<Case
> {};
31 TEST_P(ASTUtils
, PrintTemplateArgs
) {
32 auto Pair
= GetParam();
33 Annotations
Test(Pair
.AnnotatedCode
);
34 auto AST
= TestTU::withCode(Test
.code()).build();
35 struct Visitor
: RecursiveASTVisitor
<Visitor
> {
36 Visitor(std::vector
<Position
> Points
) : Points(std::move(Points
)) {}
37 bool VisitNamedDecl(const NamedDecl
*ND
) {
38 if (TemplateArgsAtPoints
.size() == Points
.size())
40 auto Pos
= sourceLocToPosition(ND
->getASTContext().getSourceManager(),
42 if (Pos
!= Points
[TemplateArgsAtPoints
.size()])
44 TemplateArgsAtPoints
.push_back(printTemplateSpecializationArgs(*ND
));
47 std::vector
<std::string
> TemplateArgsAtPoints
;
48 const std::vector
<Position
> Points
;
50 Visitor
V(Test
.points());
51 V
.TraverseDecl(AST
.getASTContext().getTranslationUnitDecl());
52 EXPECT_THAT(V
.TemplateArgsAtPoints
, ElementsAreArray(Pair
.Expected
));
55 INSTANTIATE_TEST_SUITE_P(ASTUtilsTests
, ASTUtils
,
56 ::testing::ValuesIn(std::vector
<Case
>({
59 template <class X> class Bar {};
60 template <> class ^Bar<double> {};)cpp",
64 template <class X> class Bar {};
65 template <class T, class U,
66 template<typename> class Z, int Q>
68 template struct ^Foo<int, bool, Bar, 8>;
70 struct ^Foo<T *, T, Bar, 3> {};)cpp",
71 {"<int, bool, Bar, 8>", "<T *, T, Bar, 3>"}},
74 template <int ...> void Foz() {};
75 template <> void ^Foz<3, 5, 8>() {};)cpp",
79 template <class X> class Bar {};
80 template <template <class> class ...>
82 template <> class ^Aux<Bar, Bar> {};
83 template <template <class> class T>
84 class ^Aux<T, T> {};)cpp",
85 {"<Bar, Bar>", "<T, T>"}},
88 template <typename T> T var = 1234;
89 template <> int ^var<int> = 1;)cpp",
93 template <typename T> struct Foo;
94 struct Bar { friend class Foo<int>; };
95 template <> struct ^Foo<int> {};)cpp",
104 int ^S<double> = 0;)cpp",
105 {"<T *>", "<double>"}},
108 } // namespace clangd