1 //===- unittest/AST/ASTTypeTraits.cpp - AST type traits unit tests ------===//
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 "clang/AST/ASTTypeTraits.h"
11 #include "MatchVerifier.h"
12 #include "gtest/gtest.h"
14 using namespace clang::ast_matchers
;
19 TEST(ASTNodeKind
, NoKind
) {
20 EXPECT_FALSE(ASTNodeKind().isBaseOf(ASTNodeKind()));
21 EXPECT_FALSE(ASTNodeKind().isSame(ASTNodeKind()));
24 template <typename T
> static ASTNodeKind
DNT() {
25 return ASTNodeKind::getFromNodeKind
<T
>();
28 TEST(ASTNodeKind
, IsNone
) {
29 EXPECT_TRUE(ASTNodeKind().isNone());
30 EXPECT_FALSE(DNT
<Decl
>().isNone());
31 EXPECT_FALSE(DNT
<VarDecl
>().isNone());
34 TEST(ASTNodeKind
, Bases
) {
35 EXPECT_TRUE(DNT
<Decl
>().isBaseOf(DNT
<VarDecl
>()));
36 EXPECT_FALSE(DNT
<Decl
>().isSame(DNT
<VarDecl
>()));
37 EXPECT_FALSE(DNT
<VarDecl
>().isBaseOf(DNT
<Decl
>()));
39 EXPECT_TRUE(DNT
<Decl
>().isSame(DNT
<Decl
>()));
42 TEST(DynTypedNode
, Clades
) {
43 EXPECT_TRUE(DNT
<Stmt
>().getCladeKind().isSame(DNT
<Stmt
>()));
44 EXPECT_TRUE(DNT
<Decl
>().getCladeKind().isSame(DNT
<Decl
>()));
46 EXPECT_TRUE(DNT
<CXXMethodDecl
>().getCladeKind().isSame(DNT
<Decl
>()));
47 EXPECT_TRUE(DNT
<CXXMemberCallExpr
>().getCladeKind().isSame(DNT
<Stmt
>()));
49 EXPECT_FALSE(DNT
<CXXMemberCallExpr
>().getCladeKind().isSame(DNT
<Decl
>()));
51 EXPECT_TRUE(ASTNodeKind().getCladeKind().isNone());
54 TEST(ASTNodeKind
, BaseDistances
) {
55 unsigned Distance
= 1;
56 EXPECT_TRUE(DNT
<Expr
>().isBaseOf(DNT
<Expr
>(), &Distance
));
57 EXPECT_EQ(0u, Distance
);
59 EXPECT_TRUE(DNT
<Stmt
>().isBaseOf(DNT
<IfStmt
>(), &Distance
));
60 EXPECT_EQ(1u, Distance
);
63 EXPECT_TRUE(DNT
<DeclaratorDecl
>().isBaseOf(DNT
<ParmVarDecl
>(), &Distance
));
64 EXPECT_EQ(2u, Distance
);
67 TEST(ASTNodeKind
, SameBase
) {
68 EXPECT_TRUE(DNT
<Expr
>().isBaseOf(DNT
<CallExpr
>()));
69 EXPECT_TRUE(DNT
<Expr
>().isBaseOf(DNT
<BinaryOperator
>()));
70 EXPECT_FALSE(DNT
<CallExpr
>().isBaseOf(DNT
<BinaryOperator
>()));
71 EXPECT_FALSE(DNT
<BinaryOperator
>().isBaseOf(DNT
<CallExpr
>()));
74 TEST(ASTNodeKind
, DiffBase
) {
75 EXPECT_FALSE(DNT
<Expr
>().isBaseOf(DNT
<ArrayType
>()));
76 EXPECT_FALSE(DNT
<QualType
>().isBaseOf(DNT
<FunctionDecl
>()));
77 EXPECT_FALSE(DNT
<Type
>().isSame(DNT
<QualType
>()));
80 TEST(ASTNodeKind
, MostDerivedType
) {
81 EXPECT_TRUE(DNT
<BinaryOperator
>().isSame(
82 ASTNodeKind::getMostDerivedType(DNT
<Expr
>(), DNT
<BinaryOperator
>())));
83 EXPECT_TRUE(DNT
<BinaryOperator
>().isSame(
84 ASTNodeKind::getMostDerivedType(DNT
<BinaryOperator
>(), DNT
<Expr
>())));
85 EXPECT_TRUE(DNT
<VarDecl
>().isSame(
86 ASTNodeKind::getMostDerivedType(DNT
<VarDecl
>(), DNT
<VarDecl
>())));
88 // Not related. Returns nothing.
90 ASTNodeKind::getMostDerivedType(DNT
<IfStmt
>(), DNT
<VarDecl
>()).isNone());
91 EXPECT_TRUE(ASTNodeKind::getMostDerivedType(DNT
<IfStmt
>(),
92 DNT
<BinaryOperator
>()).isNone());
95 TEST(ASTNodeKind
, MostDerivedCommonAncestor
) {
96 EXPECT_TRUE(DNT
<Expr
>().isSame(ASTNodeKind::getMostDerivedCommonAncestor(
97 DNT
<Expr
>(), DNT
<BinaryOperator
>())));
98 EXPECT_TRUE(DNT
<Expr
>().isSame(ASTNodeKind::getMostDerivedCommonAncestor(
99 DNT
<BinaryOperator
>(), DNT
<Expr
>())));
100 EXPECT_TRUE(DNT
<VarDecl
>().isSame(ASTNodeKind::getMostDerivedCommonAncestor(
101 DNT
<VarDecl
>(), DNT
<VarDecl
>())));
103 // A little related. Returns the ancestor.
105 DNT
<NamedDecl
>().isSame(ASTNodeKind::getMostDerivedCommonAncestor(
106 DNT
<CXXMethodDecl
>(), DNT
<RecordDecl
>())));
108 // Not related. Returns nothing.
109 EXPECT_TRUE(ASTNodeKind::getMostDerivedCommonAncestor(
110 DNT
<IfStmt
>(), DNT
<VarDecl
>()).isNone());
115 TEST(ASTNodeKind
, UnknownKind
) {
116 // We can construct one, but it is nowhere in the hierarchy.
117 EXPECT_FALSE(DNT
<Foo
>().isSame(DNT
<Foo
>()));
120 template <typename T
>
121 constexpr bool HasPointerIdentity
=
122 ASTNodeKind::getFromNodeKind
<T
>().hasPointerIdentity();
124 TEST(ASTNodeKind
, ConstexprHasPointerIdentity
) {
125 EXPECT_TRUE(HasPointerIdentity
<Decl
>);
126 EXPECT_TRUE(HasPointerIdentity
<Stmt
>);
127 EXPECT_FALSE(HasPointerIdentity
<TypeLoc
>);
128 EXPECT_FALSE(HasPointerIdentity
<QualType
>);
129 EXPECT_FALSE(HasPointerIdentity
<Foo
>);
131 constexpr bool DefaultConstructedHasPointerIdentity
=
132 ASTNodeKind().hasPointerIdentity();
133 EXPECT_FALSE(DefaultConstructedHasPointerIdentity
);
136 template <typename T
, typename U
>
137 constexpr bool NodeKindIsSame
=
138 ASTNodeKind::getFromNodeKind
<T
>().isSame(ASTNodeKind::getFromNodeKind
<U
>());
140 TEST(ASTNodeKind
, ConstexprIsSame
) {
141 EXPECT_TRUE((NodeKindIsSame
<Decl
, Decl
>));
142 EXPECT_FALSE((NodeKindIsSame
<Decl
, VarDecl
>));
143 EXPECT_FALSE((NodeKindIsSame
<Foo
, Foo
>));
145 constexpr bool DefaultConstructedIsSameToDefaultConstructed
=
146 ASTNodeKind().isSame(ASTNodeKind());
147 EXPECT_FALSE(DefaultConstructedIsSameToDefaultConstructed
);
150 template <typename T
>
151 constexpr bool NodeKindIsNone
= ASTNodeKind::getFromNodeKind
<T
>().isNone();
153 TEST(ASTNodeKind
, ConstexprIsNone
) {
154 EXPECT_FALSE(NodeKindIsNone
<Decl
>);
155 EXPECT_TRUE(NodeKindIsNone
<Foo
>);
157 constexpr bool DefaultConstructedIsNone
= ASTNodeKind().isNone();
158 EXPECT_TRUE(DefaultConstructedIsNone
);
161 TEST(ASTNodeKind
, Name
) {
162 EXPECT_EQ("<None>", ASTNodeKind().asStringRef());
163 #define VERIFY_NAME(Node) EXPECT_EQ(#Node, DNT<Node>().asStringRef());
164 VERIFY_NAME(TemplateArgument
);
165 VERIFY_NAME(NestedNameSpecifierLoc
);
166 VERIFY_NAME(QualType
);
167 VERIFY_NAME(TypeLoc
);
168 VERIFY_NAME(CXXCtorInitializer
);
169 VERIFY_NAME(ConceptReference
);
170 VERIFY_NAME(NestedNameSpecifier
);
172 VERIFY_NAME(CXXRecordDecl
);
174 VERIFY_NAME(CallExpr
);
176 VERIFY_NAME(ConstantArrayType
);
177 VERIFY_NAME(NonNullAttr
);
181 TEST(DynTypedNode
, DeclSourceRange
) {
182 RangeVerifier
<DynTypedNode
> Verifier
;
183 Verifier
.expectRange(1, 1, 1, 11);
184 EXPECT_TRUE(Verifier
.match("void f() {}", decl()));
187 TEST(DynTypedNode
, StmtSourceRange
) {
188 RangeVerifier
<DynTypedNode
> Verifier
;
189 Verifier
.expectRange(1, 10, 1, 11);
190 EXPECT_TRUE(Verifier
.match("void f() {}", stmt()));
193 TEST(DynTypedNode
, TypeLocSourceRange
) {
194 RangeVerifier
<DynTypedNode
> Verifier
;
195 Verifier
.expectRange(1, 1, 1, 8);
196 EXPECT_TRUE(Verifier
.match("void f() {}", typeLoc(loc(functionType()))));
199 TEST(DynTypedNode
, NNSLocSourceRange
) {
200 RangeVerifier
<DynTypedNode
> Verifier
;
201 Verifier
.expectRange(1, 33, 1, 34);
202 EXPECT_TRUE(Verifier
.match("namespace N { typedef void T; } N::T f() {}",
203 nestedNameSpecifierLoc()));
206 TEST(DynTypedNode
, AttrSourceRange
) {
207 RangeVerifier
<DynTypedNode
> Verifier
;
208 Verifier
.expectRange(1, 31, 1, 31);
209 EXPECT_TRUE(Verifier
.match("void x(char *y __attribute__((nonnull)) );",
210 ast_matchers::attr()));
213 // FIXME: add tests for ConceptReference once we add an ASTMatcher.
215 TEST(DynTypedNode
, DeclDump
) {
216 DumpVerifier Verifier
;
217 Verifier
.expectSubstring("FunctionDecl");
218 EXPECT_TRUE(Verifier
.match("void f() {}", functionDecl()));
221 TEST(DynTypedNode
, StmtDump
) {
222 DumpVerifier Verifier
;
223 Verifier
.expectSubstring("CompoundStmt");
224 EXPECT_TRUE(Verifier
.match("void f() {}", stmt()));
227 TEST(DynTypedNode
, DeclPrint
) {
228 PrintVerifier Verifier
;
229 Verifier
.expectString("void f() {\n}\n");
230 EXPECT_TRUE(Verifier
.match("void f() {}", functionDecl()));
233 TEST(DynTypedNode
, StmtPrint
) {
234 PrintVerifier Verifier
;
235 Verifier
.expectString("{\n}\n");
236 EXPECT_TRUE(Verifier
.match("void f() {}", stmt()));
239 TEST(DynTypedNode
, QualType
) {
241 DynTypedNode Node
= DynTypedNode::create(Q
);
242 EXPECT_TRUE(Node
== Node
);
243 EXPECT_FALSE(Node
< Node
);
246 TEST(DynTypedNode
, TypeLoc
) {
247 std::string code
= R
"cc(void example() { int abc; })cc";
248 auto AST
= clang::tooling::buildASTFromCode(code
);
250 match(traverse(TK_AsIs
,
251 varDecl(hasName("abc"), hasTypeLoc(typeLoc().bind("tl")))),
252 AST
->getASTContext());
253 EXPECT_EQ(matches
.size(), 1u);
255 const auto &tl
= *matches
[0].getNodeAs
<TypeLoc
>("tl");
256 DynTypedNode Node
= DynTypedNode::create(tl
);
257 EXPECT_TRUE(Node
== Node
);
258 EXPECT_FALSE(Node
< Node
);
261 TEST(DynTypedNode
, PointerTypeLoc
) {
262 std::string code
= R
"cc(void example() { int *abc; })cc";
263 auto AST
= clang::tooling::buildASTFromCode(code
);
265 match(traverse(TK_AsIs
, varDecl(hasName("abc"),
266 hasTypeLoc(typeLoc().bind("ptl")))),
267 AST
->getASTContext());
268 EXPECT_EQ(matches
.size(), 1u);
270 const auto &tl
= *matches
[0].getNodeAs
<TypeLoc
>("ptl");
271 DynTypedNode TypeLocNode
= DynTypedNode::create(tl
);
272 EXPECT_TRUE(TypeLocNode
== TypeLocNode
);
273 EXPECT_FALSE(TypeLocNode
< TypeLocNode
);
275 const auto &ptl
= *matches
[0].getNodeAs
<PointerTypeLoc
>("ptl");
276 EXPECT_EQ(&tl
, &ptl
);
277 DynTypedNode PointerTypeLocNode
= DynTypedNode::create(ptl
);
278 EXPECT_TRUE(PointerTypeLocNode
== PointerTypeLocNode
);
279 EXPECT_FALSE(PointerTypeLocNode
< PointerTypeLocNode
);