Run DCE after a LoopFlatten test to reduce spurious output [nfc]
[llvm-project.git] / clang / unittests / AST / ASTTypeTraitsTest.cpp
blobb8f58b0cc6dd70fe2727123ff82e24e217af3048
1 //===- unittest/AST/ASTTypeTraits.cpp - AST type traits unit tests ------===//
2 //
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
6 //
7 //===--------------------------------------------------------------------===//
10 #include "clang/AST/ASTTypeTraits.h"
11 #include "MatchVerifier.h"
12 #include "gtest/gtest.h"
14 using namespace clang::ast_matchers;
16 namespace clang {
17 namespace {
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);
62 Distance = 3;
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.
89 EXPECT_TRUE(
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.
104 EXPECT_TRUE(
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());
113 struct Foo {};
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);
171 VERIFY_NAME(Decl);
172 VERIFY_NAME(CXXRecordDecl);
173 VERIFY_NAME(Stmt);
174 VERIFY_NAME(CallExpr);
175 VERIFY_NAME(Type);
176 VERIFY_NAME(ConstantArrayType);
177 VERIFY_NAME(NonNullAttr);
178 #undef VERIFY_NAME
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) {
240 QualType Q;
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);
249 auto matches =
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);
264 auto matches =
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);
282 } // namespace
283 } // namespace clang