12#include "clang/AST/ASTTypeTraits.h"
13#include "llvm/ADT/STLExtras.h"
14#include "llvm/Support/ScopedPrinter.h"
15#include "gmock/gmock.h"
16#include "gtest/gtest.h"
21using testing::Contains;
27TEST(DumpASTTests, BasicInfo) {
28 std::pair<std::string, std::string> Cases[] = {
35declaration: Function - root
38 declaration: ParmVar - x
43 expression: ImplicitCast - IntegralToFloating
44 expression: BinaryOperator - +
45 expression: ImplicitCast - LValueToRValue
46 expression: UnaryOperator - *
47 expression: ImplicitCast - LValueToRValue
48 expression: DeclRef - x
49 expression: IntegerLiteral - 1
53struct S { static const int x = 0; ~S(); };
54int y = S::x + root::S().x;
58declaration: Namespace - root
59 declaration: CXXRecord - S
61 type: Qualified - const
63 expression: IntegerLiteral - 0
64 declaration: CXXDestructor
68 declaration: CXXConstructor
69 declaration: CXXConstructor
72 expression: ExprWithCleanups
73 expression: BinaryOperator - +
74 expression: ImplicitCast - LValueToRValue
75 expression: DeclRef - x
78 expression: ImplicitCast - LValueToRValue
79 expression: Member - x
80 expression: CXXBindTemporary
81 expression: CXXTemporaryObject - S
83 specifier: Namespace - root::
87struct S { static const int x = 0; };
88int y = S::x + root::S().x;
92declaration: Namespace - root
93 declaration: CXXRecord - S
95 type: Qualified - const
97 expression: IntegerLiteral - 0
98 declaration: CXXConstructor
99 declaration: CXXConstructor
100 declaration: CXXConstructor
101 declaration: CXXDestructor
104 expression: BinaryOperator - +
105 expression: ImplicitCast - LValueToRValue
106 expression: DeclRef - x
109 expression: ImplicitCast - LValueToRValue
110 expression: Member - x
111 expression: CXXTemporaryObject - S
113 specifier: Namespace - root::
117template <typename T> int tmpl() {
118 (void)tmpl<unsigned>();
124declaration: Namespace - root
125 declaration: FunctionTemplate - tmpl
126 declaration: TemplateTypeParm - T
127 declaration: Function - tmpl
131 expression: CStyleCast - ToVoid
134 expression: ImplicitCast - FunctionToPointerDecay
135 expression: DeclRef - tmpl
136 template argument: Type
137 type: Builtin - unsigned int
139 expression: DependentScopeDeclRef - value
141 type: TemplateTypeParm - T
144struct Foo { char operator+(int); };
145char root = Foo() + 42;
148declaration: Var - root
150 expression: ExprWithCleanups
151 expression: CXXOperatorCall
152 expression: ImplicitCast - FunctionToPointerDecay
153 expression: DeclRef - operator+
154 expression: MaterializeTemporary - lvalue
155 expression: CXXTemporaryObject - Foo
157 expression: IntegerLiteral - 42
168declaration: CXXMethod - root
173 expression: ImplicitCast - LValueToRValue
174 expression: Member - x
175 expression: CXXThis - const, implicit
178 for (
const auto &Case : Cases) {
181 AST.getTokens(),
AST.getASTContext());
182 EXPECT_EQ(llvm::StringRef(Case.second).trim(),
183 llvm::StringRef(llvm::to_string(Node)).trim());
191 AST.getASTContext());
192 EXPECT_EQ(Node.range, Case.range(
"var"));
193 ASSERT_THAT(Node.children, SizeIs(1)) <<
"Expected one child typeloc";
194 EXPECT_EQ(Node.children.front().range, Case.range(
"type"));
197TEST(DumpASTTests, NoRange) {
199 TU.Code =
"int varFromSource;";
202 DynTypedNode::create(*
AST.getASTContext().getTranslationUnitDecl()),
203 AST.getTokens(),
AST.getASTContext());
204 ASSERT_THAT(Node.children, Contains(withDetail(
"varFromSource")));
205 ASSERT_THAT(Node.children, Not(Contains(withDetail(
"funcFromHeader"))));
206 EXPECT_THAT(Node.arcana, testing::StartsWith(
"TranslationUnitDecl "));
207 ASSERT_FALSE(Node.range) <<
"Expected no range for translation unit";
210TEST(DumpASTTests, Arcana) {
213 AST.getASTContext());
214 EXPECT_THAT(Node.arcana, testing::StartsWith(
"VarDecl "));
215 EXPECT_THAT(Node.arcana, testing::EndsWith(
" 'int' external-linkage"));
216 ASSERT_THAT(Node.children, SizeIs(1)) <<
"Expected one child typeloc";
217 EXPECT_THAT(Node.children.front().arcana, testing::StartsWith(
"QualType "));
220TEST(DumpASTTests, UnbalancedBraces) {
224 Annotations Case(
"/*error-ok*/ $func[[int main() {]]");
227 AST.getTokens(),
AST.getASTContext());
228 ASSERT_EQ(Node.range, Case.range(
"func"));
231bool hasDetail(
const ASTNode &Node, llvm::StringRef Detail) {
232 if (Node.detail == Detail)
234 return llvm::any_of(Node.children, [&Detail](
const ASTNode &Child) {
235 return hasDetail(Child, Detail);
239TEST(DumpASTTests, PackIndexedConcept) {
241template <template <class> concept... CC, CC...[0] T>
244 TU.ExtraArgs = {"-std=c++2d"};
247 DynTypedNode::create(*
AST.getASTContext().getTranslationUnitDecl()),
248 AST.getTokens(),
AST.getASTContext());
250 EXPECT_TRUE(hasDetail(Node,
"CC...[0]"));
253TEST(DumpASTTests, NestedTemplates) {
256 const char *Code = R
"cpp(
259 template <typename U>
265template <typename V, typename W>
267 return TypeA<V>::template TypeB<W>::Value;
272 const NamedDecl &Func =
findDecl(
AST, [](
const NamedDecl &D) {
273 return isa<FunctionDecl>(D) &&
D.getNameAsString() ==
"func";
277 dumpAST(DynTypedNode::create(Func),
AST.getTokens(),
AST.getASTContext());
279 EXPECT_EQ(Node.kind,
"Function");
Same as llvm::Annotations, but adjusts functions to LSP-specific types for positions and ranges.
Stores and provides access to parsed AST.
FIXME: Skip testing on windows temporarily due to the different escaping code mode.
const NamedDecl & findDecl(ParsedAST &AST, llvm::StringRef QName)
ASTNode dumpAST(const DynTypedNode &N, const syntax::TokenBuffer &Tokens, const ASTContext &Ctx)
TEST(BackgroundQueueTest, Priority)
const NamedDecl & findUnqualifiedDecl(ParsedAST &AST, llvm::StringRef Name)
===– Representation.cpp - ClangDoc Representation --------—*- C++ -*-===//
Simplified description of a clang AST node.
static TestTU withHeaderCode(llvm::StringRef HeaderCode)
static TestTU withCode(llvm::StringRef Code)