1 //===- unittests/AST/TypePrinterTest.cpp --- Type 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 QualType::print() and related methods. 10 // 11 //===----------------------------------------------------------------------===// 12 13 #include "ASTPrint.h" 14 #include "clang/AST/ASTContext.h" 15 #include "clang/ASTMatchers/ASTMatchFinder.h" 16 #include "clang/Tooling/Tooling.h" 17 #include "llvm/ADT/SmallString.h" 18 #include "gtest/gtest.h" 19 20 using namespace clang; 21 using namespace ast_matchers; 22 using namespace tooling; 23 24 namespace { 25 26 static void PrintType(raw_ostream &Out, const ASTContext *Context, 27 const QualType *T, 28 PrintingPolicyAdjuster PolicyAdjuster) { 29 assert(T && !T->isNull() && "Expected non-null Type"); 30 PrintingPolicy Policy = Context->getPrintingPolicy(); 31 if (PolicyAdjuster) 32 PolicyAdjuster(Policy); 33 T->print(Out, Policy); 34 } 35 36 ::testing::AssertionResult 37 PrintedTypeMatches(StringRef Code, const std::vector<std::string> &Args, 38 const DeclarationMatcher &NodeMatch, 39 StringRef ExpectedPrinted, 40 PrintingPolicyAdjuster PolicyAdjuster) { 41 return PrintedNodeMatches<QualType>(Code, Args, NodeMatch, ExpectedPrinted, 42 "", PrintType, PolicyAdjuster); 43 } 44 45 } // unnamed namespace 46 47 TEST(TypePrinter, TemplateId) { 48 std::string Code = R"cpp( 49 namespace N { 50 template <typename> struct Type {}; 51 52 template <typename T> 53 void Foo(const Type<T> &Param); 54 } 55 )cpp"; 56 auto Matcher = parmVarDecl(hasType(qualType().bind("id"))); 57 58 ASSERT_TRUE(PrintedTypeMatches( 59 Code, {}, Matcher, "const Type<T> &", 60 [](PrintingPolicy &Policy) { Policy.FullyQualifiedName = false; })); 61 62 ASSERT_TRUE(PrintedTypeMatches( 63 Code, {}, Matcher, "const N::Type<T> &", 64 [](PrintingPolicy &Policy) { Policy.FullyQualifiedName = true; })); 65 } 66 67 TEST(TypePrinter, ParamsUglified) { 68 llvm::StringLiteral Code = R"cpp( 69 template <typename _Tp, template <typename> class __f> 70 const __f<_Tp&> *A = nullptr; 71 )cpp"; 72 auto Clean = [](PrintingPolicy &Policy) { 73 Policy.CleanUglifiedParameters = true; 74 }; 75 76 ASSERT_TRUE(PrintedTypeMatches(Code, {}, 77 varDecl(hasType(qualType().bind("id"))), 78 "const __f<_Tp &> *", nullptr)); 79 ASSERT_TRUE(PrintedTypeMatches(Code, {}, 80 varDecl(hasType(qualType().bind("id"))), 81 "const f<Tp &> *", Clean)); 82 } 83 84 TEST(TypePrinter, TemplateIdWithNTTP) { 85 constexpr char Code[] = R"cpp( 86 template <int N> 87 struct Str { 88 constexpr Str(char const (&s)[N]) { __builtin_memcpy(value, s, N); } 89 char value[N]; 90 }; 91 template <Str> class ASCII {}; 92 93 ASCII<"this nontype template argument is too long to print"> x; 94 )cpp"; 95 auto Matcher = classTemplateSpecializationDecl( 96 hasName("ASCII"), has(cxxConstructorDecl( 97 isMoveConstructor(), 98 has(parmVarDecl(hasType(qualType().bind("id"))))))); 99 100 ASSERT_TRUE(PrintedTypeMatches( 101 Code, {"-std=c++20"}, Matcher, 102 R"(ASCII<{"this nontype template argument is [...]"}> &&)", 103 [](PrintingPolicy &Policy) { 104 Policy.EntireContentsOfLargeArray = false; 105 })); 106 107 ASSERT_TRUE(PrintedTypeMatches( 108 Code, {"-std=c++20"}, Matcher, 109 R"(ASCII<{"this nontype template argument is too long to print"}> &&)", 110 [](PrintingPolicy &Policy) { 111 Policy.EntireContentsOfLargeArray = true; 112 })); 113 } 114