//===- unittest/Tooling/StandardLibrary.cpp -------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// #include "clang/Tooling/Inclusions/StandardLibrary.h" #include "clang/AST/ASTContext.h" #include "clang/AST/Decl.h" #include "clang/AST/DeclarationName.h" #include "clang/Testing/TestAST.h" #include "llvm/ADT/StringRef.h" #include "llvm/Support/Casting.h" #include "llvm/Support/ScopedPrinter.h" #include "gmock/gmock.h" #include "gtest/gtest.h" using ::testing::ElementsAre; namespace clang { namespace tooling { namespace { const NamedDecl &lookup(TestAST &AST, llvm::StringRef Name) { TranslationUnitDecl *TU = AST.context().getTranslationUnitDecl(); auto Result = TU->lookup(DeclarationName(&AST.context().Idents.get(Name))); assert(!Result.empty() && "Lookup failed"); assert(Result.isSingleResult() && "Lookup returned multiple results"); return *Result.front(); } TEST(StdlibTest, All) { auto VectorH = stdlib::Header::named(""); EXPECT_TRUE(VectorH); EXPECT_EQ(llvm::to_string(*VectorH), ""); EXPECT_FALSE(stdlib::Header::named("HeadersTests.cpp")); auto Vector = stdlib::Symbol::named("std::", "vector"); EXPECT_TRUE(Vector); EXPECT_EQ(llvm::to_string(*Vector), "std::vector"); EXPECT_FALSE(stdlib::Symbol::named("std::", "dongle")); EXPECT_FALSE(stdlib::Symbol::named("clang::", "ASTContext")); EXPECT_EQ(Vector->header(), *VectorH); EXPECT_THAT(Vector->headers(), ElementsAre(*VectorH)); } TEST(StdlibTest, Recognizer) { TestAST AST(R"cpp( namespace std { inline namespace inl { template struct vector { class nested {}; }; class secret {}; } // inl inline namespace __1 { namespace chrono { inline namespace chrono_inl { class system_clock {}; } // chrono_inl } // chrono } // __1 } // std // C Standard Library structure defined in struct div_t {}; class vector {}; std::vector vec; std::vector::nested nest; std::secret sec; std::chrono::system_clock clock; div_t div; )cpp"); auto &VectorNonstd = lookup(AST, "vector"); auto *Vec = cast(lookup(AST, "vec")).getType()->getAsCXXRecordDecl(); auto *Nest = cast(lookup(AST, "nest")).getType()->getAsCXXRecordDecl(); auto *Clock = cast(lookup(AST, "clock")).getType()->getAsCXXRecordDecl(); auto *Sec = cast(lookup(AST, "sec")).getType()->getAsCXXRecordDecl(); auto *CDivT = cast(lookup(AST, "div")).getType()->getAsCXXRecordDecl(); stdlib::Recognizer Recognizer; EXPECT_EQ(Recognizer(&VectorNonstd), llvm::None); EXPECT_EQ(Recognizer(Vec), stdlib::Symbol::named("std::", "vector")); EXPECT_EQ(Recognizer(Nest), stdlib::Symbol::named("std::", "vector")); EXPECT_EQ(Recognizer(Clock), stdlib::Symbol::named("std::chrono::", "system_clock")); EXPECT_EQ(Recognizer(CDivT), stdlib::Symbol::named("", "div_t")); EXPECT_EQ(Recognizer(Sec), llvm::None); } } // namespace } // namespace tooling } // namespace clang