1 //===- unittests/AST/ASTDumperTest.cpp --- Test of AST node dump() methods ===//
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 //===----------------------------------------------------------------------===//
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
14 //===----------------------------------------------------------------------===//
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"
24 using namespace clang
;
25 using namespace ast_matchers
;
28 using testing::ElementsAre
;
29 using testing::StartsWith
;
31 std::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
>()))
36 else if (auto *TD
= Lookup
.find_first
<FunctionTemplateDecl
>())
37 D
= TD
->getTemplatedDecl();
38 EXPECT_NE(D
, nullptr) << Name
;
41 EXPECT_NE(D
->getTypeSourceInfo(), nullptr);
42 if (!D
->getTypeSourceInfo())
46 llvm::raw_string_ostream
OS(S
);
47 D
->getTypeSourceInfo()->getTypeLoc().dump(OS
, Ctx
);
49 // Split result into lines.
50 std::vector
<std::string
> Result
;
51 auto Remaining
= llvm::StringRef(S
).trim("\n");
52 while (!Remaining
.empty()) {
53 auto [First
, Rest
] = Remaining
.split('\n');
54 Result
.push_back(First
.str());
60 TEST(ASTDumper
, TypeLocChain
) {
65 dumpTypeLoc("x", AST
.context()),
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'"));
73 TEST(ASTDumper
, AutoType
) {
74 TestInputs
Inputs(R
"cc(
75 template <class, class> concept C = true;
76 C<int> auto str1 = "hello
";
79 Inputs
.ExtraArgs
.push_back("-std=c++20");
82 dumpTypeLoc("str1", AST
.context()),
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()),
90 "AutoTypeLoc <input.mm:4:5> 'auto' undeduced"));
94 TEST(ASTDumper
, FunctionTypeLoc
) {
96 void x(int, double *y);
98 auto trailing() -> int;
100 template <class T> int tmpl(T&&);
103 dumpTypeLoc("x", AST
.context()),
105 "FunctionProtoTypeLoc <input.mm:2:5, col:26> 'void (int, "
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'"));
114 EXPECT_THAT(dumpTypeLoc("trailing", AST
.context()),
116 "FunctionProtoTypeLoc <input.mm:4:5, col:24> "
117 "'auto () -> int' trailing_return cdecl",
118 "`-BuiltinTypeLoc <col:24> 'int'"));
121 dumpTypeLoc("tmpl", AST
.context()),
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'"));
131 // Dynamic-exception-spec needs C++14 or earlier.
132 TestInputs
Throws(R
"cc(
133 void throws() throw(int);
135 Throws
.ExtraArgs
.push_back("-std=c++14");
136 AST
= TestAST(Throws
);
137 EXPECT_THAT(dumpTypeLoc("throws", AST
.context()),
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'"));