1//===- unittests/AST/ASTDumperTest.cpp --- Test of AST node dump() methods ===//
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//===----------------------------------------------------------------------===//
8//
9// This file contains tests for TypeLoc::dump() and related methods.
10// Most of these are lit tests via clang -ast-dump. However some nodes are not
11// included in dumps of (TranslationUnit)Decl, but still relevant when dumped
12// directly.
13//
14//===----------------------------------------------------------------------===//
15
16#include "ASTPrint.h"
17#include "clang/AST/ASTContext.h"
18#include "clang/AST/Decl.h"
19#include "clang/Testing/TestAST.h"
20#include "llvm/ADT/StringRef.h"
21#include "gmock/gmock.h"
22#include "gtest/gtest.h"
23
24using namespace clang;
25using namespace ast_matchers;
26
27namespace {
28using testing::ElementsAre;
29using testing::StartsWith;
30
31std::vector<std::string> dumpTypeLoc(llvm::StringRef Name, ASTContext &Ctx) {
32 auto Lookup = Ctx.getTranslationUnitDecl()->lookup(&Ctx.Idents.get(Name));
33 DeclaratorDecl *D = nullptr;
34 if ((D = Lookup.find_first<DeclaratorDecl>()))
35 ;
36 else if (auto *TD = Lookup.find_first<FunctionTemplateDecl>())
37 D = TD->getTemplatedDecl();
38 EXPECT_NE(D, nullptr) << Name;
39 if (!D)
40 return {};
41 EXPECT_NE(D->getTypeSourceInfo(), nullptr);
42 if (!D->getTypeSourceInfo())
43 return {};
44 std::string S;
45 {
46 llvm::raw_string_ostream OS(S);
47 D->getTypeSourceInfo()->getTypeLoc().dump(OS, Ctx);
48 }
49 // Split result into lines.
50 std::vector<std::string> Result;
51 auto Remaining = llvm::StringRef(S).trim(Chars: "\n");
52 while (!Remaining.empty()) {
53 auto [First, Rest] = Remaining.split(Separator: '\n');
54 Result.push_back(x: First.str());
55 Remaining = Rest;
56 }
57 return Result;
58}
59
60TEST(ASTDumper, TypeLocChain) {
61 TestAST AST(R"cc(
62 const int **x;
63 )cc");
64 EXPECT_THAT(
65 dumpTypeLoc("x", AST.context()),
66 ElementsAre(""
67 "PointerTypeLoc <input.mm:2:11, col:16> 'const int **'",
68 "`-PointerTypeLoc <col:11, col:15> 'const int *'",
69 " `-QualifiedTypeLoc <col:11> 'const int'",
70 " `-BuiltinTypeLoc <col:11> 'int'"));
71}
72
73TEST(ASTDumper, AutoType) {
74 TestInputs Inputs(R"cc(
75 template <class, class> concept C = true;
76 C<int> auto str1 = "hello";
77 auto str2 = "hello";
78 )cc");
79 Inputs.ExtraArgs.push_back(x: "-std=c++20");
80 TestAST AST(Inputs);
81 EXPECT_THAT(
82 dumpTypeLoc("str1", AST.context()),
83 ElementsAre(""
84 "AutoTypeLoc <input.mm:3:5, col:12> 'C<int> auto' undeduced",
85 StartsWith("|-Concept"), //
86 "`-TemplateArgument <col:7> type 'int'",
87 StartsWith(" `-BuiltinType")));
88 EXPECT_THAT(dumpTypeLoc("str2", AST.context()),
89 ElementsAre(""
90 "AutoTypeLoc <input.mm:4:5> 'auto' undeduced"));
91}
92
93
94TEST(ASTDumper, FunctionTypeLoc) {
95 TestAST AST(R"cc(
96 void x(int, double *y);
97
98 auto trailing() -> int;
99
100 template <class T> int tmpl(T&&);
101 )cc");
102 EXPECT_THAT(
103 dumpTypeLoc("x", AST.context()),
104 ElementsAre(""
105 "FunctionProtoTypeLoc <input.mm:2:5, col:26> 'void (int, "
106 "double *)' cdecl",
107 StartsWith("|-ParmVarDecl"),
108 "| `-BuiltinTypeLoc <col:12> 'int'",
109 StartsWith("|-ParmVarDecl"),
110 "| `-PointerTypeLoc <col:17, col:24> 'double *'",
111 "| `-BuiltinTypeLoc <col:17> 'double'",
112 "`-BuiltinTypeLoc <col:5> 'void'"));
113
114 EXPECT_THAT(dumpTypeLoc("trailing", AST.context()),
115 ElementsAre(""
116 "FunctionProtoTypeLoc <input.mm:4:5, col:24> "
117 "'auto () -> int' trailing_return cdecl",
118 "`-BuiltinTypeLoc <col:24> 'int'"));
119
120 EXPECT_THAT(
121 dumpTypeLoc("tmpl", AST.context()),
122 ElementsAre(""
123 "FunctionProtoTypeLoc <input.mm:6:24, col:36> "
124 "'int (T &&)' cdecl",
125 StartsWith("|-ParmVarDecl"),
126 "| `-RValueReferenceTypeLoc <col:33, col:34> 'T &&'",
127 "| `-TemplateTypeParmTypeLoc <col:33> 'T' depth 0 index 0",
128 StartsWith("| `-TemplateTypeParm"),
129 "`-BuiltinTypeLoc <col:24> 'int'"));
130
131 // Dynamic-exception-spec needs C++14 or earlier.
132 TestInputs Throws(R"cc(
133 void throws() throw(int);
134 )cc");
135 Throws.ExtraArgs.push_back(x: "-std=c++14");
136 AST = TestAST(Throws);
137 EXPECT_THAT(dumpTypeLoc("throws", AST.context()),
138 ElementsAre(""
139 "FunctionProtoTypeLoc <input.mm:2:5, col:28> "
140 "'void () throw(int)' exceptionspec_dynamic cdecl",
141 // FIXME: include TypeLoc for int
142 "|-Exceptions: 'int'",
143 "`-BuiltinTypeLoc <col:5> 'void'"));
144}
145
146} // namespace
147

source code of clang/unittests/AST/ASTDumperTest.cpp