1 //===- unittest/Tooling/StandardLibrary.cpp -------------------------------===// 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 #include "clang/Tooling/Inclusions/StandardLibrary.h" 10 #include "clang/AST/ASTContext.h" 11 #include "clang/AST/Decl.h" 12 #include "clang/AST/DeclarationName.h" 13 #include "clang/Testing/TestAST.h" 14 #include "llvm/ADT/StringRef.h" 15 #include "llvm/Support/Casting.h" 16 #include "llvm/Support/ScopedPrinter.h" 17 18 #include "gmock/gmock.h" 19 #include "gtest/gtest.h" 20 21 using ::testing::ElementsAre; 22 23 namespace clang { 24 namespace tooling { 25 namespace { 26 27 const NamedDecl &lookup(TestAST &AST, llvm::StringRef Name) { 28 TranslationUnitDecl *TU = AST.context().getTranslationUnitDecl(); 29 auto Result = TU->lookup(DeclarationName(&AST.context().Idents.get(Name))); 30 assert(!Result.empty() && "Lookup failed"); 31 assert(Result.isSingleResult() && "Lookup returned multiple results"); 32 return *Result.front(); 33 } 34 35 TEST(StdlibTest, All) { 36 auto VectorH = stdlib::Header::named("<vector>"); 37 EXPECT_TRUE(VectorH); 38 EXPECT_EQ(llvm::to_string(*VectorH), "<vector>"); 39 EXPECT_FALSE(stdlib::Header::named("HeadersTests.cpp")); 40 41 auto Vector = stdlib::Symbol::named("std::", "vector"); 42 EXPECT_TRUE(Vector); 43 EXPECT_EQ(llvm::to_string(*Vector), "std::vector"); 44 EXPECT_FALSE(stdlib::Symbol::named("std::", "dongle")); 45 EXPECT_FALSE(stdlib::Symbol::named("clang::", "ASTContext")); 46 47 EXPECT_EQ(Vector->header(), *VectorH); 48 EXPECT_THAT(Vector->headers(), ElementsAre(*VectorH)); 49 } 50 51 TEST(StdlibTest, Recognizer) { 52 TestAST AST(R"cpp( 53 namespace std { 54 inline namespace inl { 55 56 template <typename> 57 struct vector { class nested {}; }; 58 59 class secret {}; 60 61 } // inl 62 63 inline namespace __1 { 64 namespace chrono { 65 inline namespace chrono_inl { 66 class system_clock {}; 67 } // chrono_inl 68 } // chrono 69 } // __1 70 71 } // std 72 73 // C Standard Library structure defined in <stdlib.h> 74 struct div_t {}; 75 76 class vector {}; 77 std::vector<int> vec; 78 std::vector<int>::nested nest; 79 std::secret sec; 80 std::chrono::system_clock clock; 81 82 div_t div; 83 )cpp"); 84 85 auto &VectorNonstd = lookup(AST, "vector"); 86 auto *Vec = cast<VarDecl>(lookup(AST, "vec")).getType()->getAsCXXRecordDecl(); 87 auto *Nest = 88 cast<VarDecl>(lookup(AST, "nest")).getType()->getAsCXXRecordDecl(); 89 auto *Clock = 90 cast<VarDecl>(lookup(AST, "clock")).getType()->getAsCXXRecordDecl(); 91 auto *Sec = cast<VarDecl>(lookup(AST, "sec")).getType()->getAsCXXRecordDecl(); 92 auto *CDivT = 93 cast<VarDecl>(lookup(AST, "div")).getType()->getAsCXXRecordDecl(); 94 95 stdlib::Recognizer Recognizer; 96 97 EXPECT_EQ(Recognizer(&VectorNonstd), llvm::None); 98 EXPECT_EQ(Recognizer(Vec), stdlib::Symbol::named("std::", "vector")); 99 EXPECT_EQ(Recognizer(Nest), stdlib::Symbol::named("std::", "vector")); 100 EXPECT_EQ(Recognizer(Clock), 101 stdlib::Symbol::named("std::chrono::", "system_clock")); 102 EXPECT_EQ(Recognizer(CDivT), stdlib::Symbol::named("", "div_t")); 103 EXPECT_EQ(Recognizer(Sec), llvm::None); 104 } 105 106 } // namespace 107 } // namespace tooling 108 } // namespace clang 109