Revert "[llvm] Improve llvm.objectsize computation by computing GEP, alloca and mallo...
[llvm-project.git] / clang / unittests / AST / NamedDeclPrinterTest.cpp
blobcd833725b448d4ad83ee5b6bbb99b84a45563c78
1 //===- unittests/AST/NamedDeclPrinterTest.cpp --- NamedDecl printer 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 //===----------------------------------------------------------------------===//
8 //
9 // This file contains tests for NamedDecl::printQualifiedName().
11 // These tests have a coding convention:
12 // * declaration to be printed is named 'A' unless it should have some special
13 // name (e.g., 'operator+');
14 // * additional helper declarations are 'Z', 'Y', 'X' and so on.
16 //===----------------------------------------------------------------------===//
18 #include "ASTPrint.h"
19 #include "clang/AST/ASTContext.h"
20 #include "clang/AST/Decl.h"
21 #include "clang/AST/PrettyPrinter.h"
22 #include "clang/ASTMatchers/ASTMatchFinder.h"
23 #include "clang/Tooling/Tooling.h"
24 #include "llvm/ADT/SmallString.h"
25 #include "llvm/Support/raw_ostream.h"
26 #include "gtest/gtest.h"
28 using namespace clang;
29 using namespace ast_matchers;
30 using namespace tooling;
32 namespace {
34 class PrintMatch : public MatchFinder::MatchCallback {
35 SmallString<1024> Printed;
36 unsigned NumFoundDecls;
37 std::function<void(llvm::raw_ostream &OS, const NamedDecl *)> Printer;
39 public:
40 explicit PrintMatch(
41 std::function<void(llvm::raw_ostream &OS, const NamedDecl *)> Printer)
42 : NumFoundDecls(0), Printer(std::move(Printer)) {}
44 void run(const MatchFinder::MatchResult &Result) override {
45 const NamedDecl *ND = Result.Nodes.getNodeAs<NamedDecl>("id");
46 if (!ND)
47 return;
48 NumFoundDecls++;
49 if (NumFoundDecls > 1)
50 return;
52 llvm::raw_svector_ostream Out(Printed);
53 Printer(Out, ND);
56 StringRef getPrinted() const {
57 return Printed;
60 unsigned getNumFoundDecls() const {
61 return NumFoundDecls;
65 ::testing::AssertionResult PrintedDeclMatches(
66 StringRef Code, const std::vector<std::string> &Args,
67 const DeclarationMatcher &NodeMatch, StringRef ExpectedPrinted,
68 StringRef FileName,
69 std::function<void(llvm::raw_ostream &, const NamedDecl *)> Print) {
70 return PrintedNodeMatches<NamedDecl>(
71 Code, Args, NodeMatch, ExpectedPrinted, FileName,
72 [Print](llvm::raw_ostream &Out, const ASTContext *Context,
73 const NamedDecl *ND,
74 PrintingPolicyAdjuster PolicyAdjuster) { Print(Out, ND); });
77 ::testing::AssertionResult
78 PrintedNamedDeclMatches(StringRef Code, const std::vector<std::string> &Args,
79 bool SuppressUnwrittenScope,
80 const DeclarationMatcher &NodeMatch,
81 StringRef ExpectedPrinted, StringRef FileName) {
82 return PrintedDeclMatches(Code, Args, NodeMatch, ExpectedPrinted, FileName,
83 [=](llvm::raw_ostream &Out, const NamedDecl *ND) {
84 auto Policy =
85 ND->getASTContext().getPrintingPolicy();
86 Policy.SuppressUnwrittenScope =
87 SuppressUnwrittenScope;
88 ND->printQualifiedName(Out, Policy);
89 });
92 ::testing::AssertionResult
93 PrintedNamedDeclCXX98Matches(StringRef Code, StringRef DeclName,
94 StringRef ExpectedPrinted) {
95 std::vector<std::string> Args(1, "-std=c++98");
96 return PrintedNamedDeclMatches(Code, Args,
97 /*SuppressUnwrittenScope*/ false,
98 namedDecl(hasName(DeclName)).bind("id"),
99 ExpectedPrinted, "input.cc");
102 ::testing::AssertionResult
103 PrintedWrittenNamedDeclCXX11Matches(StringRef Code, StringRef DeclName,
104 StringRef ExpectedPrinted) {
105 std::vector<std::string> Args(1, "-std=c++11");
106 return PrintedNamedDeclMatches(Code, Args,
107 /*SuppressUnwrittenScope*/ true,
108 namedDecl(hasName(DeclName)).bind("id"),
109 ExpectedPrinted, "input.cc");
112 ::testing::AssertionResult
113 PrintedWrittenPropertyDeclObjCMatches(StringRef Code, StringRef DeclName,
114 StringRef ExpectedPrinted) {
115 std::vector<std::string> Args{"-std=c++11", "-xobjective-c++"};
116 return PrintedNamedDeclMatches(Code, Args,
117 /*SuppressUnwrittenScope*/ true,
118 objcPropertyDecl(hasName(DeclName)).bind("id"),
119 ExpectedPrinted, "input.m");
122 ::testing::AssertionResult
123 PrintedNestedNameSpecifierMatches(StringRef Code, StringRef DeclName,
124 StringRef ExpectedPrinted) {
125 std::vector<std::string> Args{"-std=c++11"};
126 return PrintedDeclMatches(Code, Args, namedDecl(hasName(DeclName)).bind("id"),
127 ExpectedPrinted, "input.cc",
128 [](llvm::raw_ostream &Out, const NamedDecl *D) {
129 D->printNestedNameSpecifier(Out);
133 } // unnamed namespace
135 TEST(NamedDeclPrinter, TestNamespace1) {
136 ASSERT_TRUE(PrintedNamedDeclCXX98Matches(
137 "namespace { int A; }",
138 "A",
139 "(anonymous namespace)::A"));
142 TEST(NamedDeclPrinter, TestNamespace2) {
143 ASSERT_TRUE(PrintedWrittenNamedDeclCXX11Matches(
144 "inline namespace Z { namespace { int A; } }",
145 "A",
146 "A"));
149 TEST(NamedDeclPrinter, TestUnscopedUnnamedEnum) {
150 ASSERT_TRUE(PrintedWrittenNamedDeclCXX11Matches(
151 "enum { A };",
152 "A",
153 "A"));
156 TEST(NamedDeclPrinter, TestNamedEnum) {
157 ASSERT_TRUE(PrintedWrittenNamedDeclCXX11Matches(
158 "enum X { A };",
159 "A",
160 "A"));
163 TEST(NamedDeclPrinter, TestScopedNamedEnum) {
164 ASSERT_TRUE(PrintedWrittenNamedDeclCXX11Matches(
165 "enum class X { A };",
166 "A",
167 "X::A"));
170 TEST(NamedDeclPrinter, TestClassWithUnscopedUnnamedEnum) {
171 ASSERT_TRUE(PrintedWrittenNamedDeclCXX11Matches(
172 "class X { enum { A }; };",
173 "A",
174 "X::A"));
177 TEST(NamedDeclPrinter, TestClassWithUnscopedNamedEnum) {
178 ASSERT_TRUE(PrintedWrittenNamedDeclCXX11Matches(
179 "class X { enum Y { A }; };",
180 "A",
181 "X::A"));
184 TEST(NamedDeclPrinter, TestClassWithScopedNamedEnum) {
185 ASSERT_TRUE(PrintedWrittenNamedDeclCXX11Matches(
186 "class X { enum class Y { A }; };",
187 "A",
188 "X::Y::A"));
191 TEST(NamedDeclPrinter, TestLinkageInNamespace) {
192 ASSERT_TRUE(PrintedWrittenNamedDeclCXX11Matches(
193 "namespace X { extern \"C\" { int A; } }",
194 "A",
195 "X::A"));
198 TEST(NamedDeclPrinter, TestObjCClassExtension) {
199 const char *Code =
201 @interface Obj
202 @end
204 @interface Obj ()
205 @property(nonatomic) int property;
206 @end
208 ASSERT_TRUE(PrintedWrittenPropertyDeclObjCMatches(
209 Code,
210 "property",
211 "Obj::property"));
214 TEST(NamedDeclPrinter, TestInstanceObjCClassExtension) {
215 const char *Code =
217 @interface ObjC
218 @end
219 @interface ObjC () {
220 char data; // legal with non-fragile ABI.
222 @end
225 std::vector<std::string> Args{
226 "-std=c++11", "-xobjective-c++",
227 "-fobjc-runtime=macosx" /*force to use non-fragile ABI*/};
228 ASSERT_TRUE(PrintedNamedDeclMatches(Code, Args,
229 /*SuppressUnwrittenScope*/ true,
230 namedDecl(hasName("data")).bind("id"),
231 // not "::data"
232 "ObjC::data", "input.mm"));
235 TEST(NamedDeclPrinter, TestObjCClassExtensionWithGetter) {
236 const char *Code =
238 @interface Obj
239 @end
241 @interface Obj ()
242 @property(nonatomic, getter=myPropertyGetter) int property;
243 @end
245 ASSERT_TRUE(PrintedWrittenPropertyDeclObjCMatches(
246 Code,
247 "property",
248 "Obj::property"));
251 TEST(NamedDeclPrinter, NestedNameSpecifierSimple) {
252 const char *Code =
254 namespace foo { namespace bar { void func(); } }
256 ASSERT_TRUE(PrintedNestedNameSpecifierMatches(Code, "func", "foo::bar::"));
259 TEST(NamedDeclPrinter, NestedNameSpecifierTemplateArgs) {
260 const char *Code =
262 template <class T> struct vector;
263 template <> struct vector<int> { int method(); };
265 ASSERT_TRUE(
266 PrintedNestedNameSpecifierMatches(Code, "method", "vector<int>::"));