xref: /llvm-project/clang/unittests/Tooling/StandardLibraryTest.cpp (revision 756c20561efa1e58bd7d2a6df1499997b6b52e23)
146a6f5aeSKirill Bobyrev //===- unittest/Tooling/StandardLibrary.cpp -------------------------------===//
246a6f5aeSKirill Bobyrev //
346a6f5aeSKirill Bobyrev // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
446a6f5aeSKirill Bobyrev // See https://llvm.org/LICENSE.txt for license information.
546a6f5aeSKirill Bobyrev // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
646a6f5aeSKirill Bobyrev //
746a6f5aeSKirill Bobyrev //===----------------------------------------------------------------------===//
846a6f5aeSKirill Bobyrev 
946a6f5aeSKirill Bobyrev #include "clang/Tooling/Inclusions/StandardLibrary.h"
10a7691deeSSam McCall #include "clang/AST/ASTContext.h"
1146a6f5aeSKirill Bobyrev #include "clang/AST/Decl.h"
1246a6f5aeSKirill Bobyrev #include "clang/AST/DeclarationName.h"
13a7691deeSSam McCall #include "clang/Testing/TestAST.h"
1446a6f5aeSKirill Bobyrev #include "llvm/ADT/StringRef.h"
1546a6f5aeSKirill Bobyrev #include "llvm/Support/Casting.h"
1646a6f5aeSKirill Bobyrev #include "llvm/Support/ScopedPrinter.h"
1746a6f5aeSKirill Bobyrev 
1846a6f5aeSKirill Bobyrev #include "gmock/gmock.h"
1946a6f5aeSKirill Bobyrev #include "gtest/gtest.h"
2046a6f5aeSKirill Bobyrev 
21e1aaa314SSam McCall using ::testing::Contains;
2246a6f5aeSKirill Bobyrev using ::testing::ElementsAre;
2346a6f5aeSKirill Bobyrev 
2446a6f5aeSKirill Bobyrev namespace clang {
2546a6f5aeSKirill Bobyrev namespace tooling {
2646a6f5aeSKirill Bobyrev namespace {
2746a6f5aeSKirill Bobyrev 
lookup(TestAST & AST,llvm::StringRef Name)28a7691deeSSam McCall const NamedDecl &lookup(TestAST &AST, llvm::StringRef Name) {
29a7691deeSSam McCall   TranslationUnitDecl *TU = AST.context().getTranslationUnitDecl();
30a7691deeSSam McCall   auto Result = TU->lookup(DeclarationName(&AST.context().Idents.get(Name)));
3146a6f5aeSKirill Bobyrev   assert(!Result.empty() && "Lookup failed");
3246a6f5aeSKirill Bobyrev   assert(Result.isSingleResult() && "Lookup returned multiple results");
3346a6f5aeSKirill Bobyrev   return *Result.front();
3446a6f5aeSKirill Bobyrev }
3546a6f5aeSKirill Bobyrev 
TEST(StdlibTest,All)3646a6f5aeSKirill Bobyrev TEST(StdlibTest, All) {
3746a6f5aeSKirill Bobyrev   auto VectorH = stdlib::Header::named("<vector>");
3846a6f5aeSKirill Bobyrev   EXPECT_TRUE(VectorH);
39e1aaa314SSam McCall   EXPECT_EQ(VectorH->name(), "<vector>");
4046a6f5aeSKirill Bobyrev   EXPECT_EQ(llvm::to_string(*VectorH), "<vector>");
4146a6f5aeSKirill Bobyrev   EXPECT_FALSE(stdlib::Header::named("HeadersTests.cpp"));
4246a6f5aeSKirill Bobyrev 
431285172cSViktoriia Bakalova   EXPECT_TRUE(stdlib::Header::named("<vector>", stdlib::Lang::CXX));
441285172cSViktoriia Bakalova   EXPECT_FALSE(stdlib::Header::named("<vector>", stdlib::Lang::C));
451285172cSViktoriia Bakalova 
4646a6f5aeSKirill Bobyrev   auto Vector = stdlib::Symbol::named("std::", "vector");
4746a6f5aeSKirill Bobyrev   EXPECT_TRUE(Vector);
48e1aaa314SSam McCall   EXPECT_EQ(Vector->scope(), "std::");
49e1aaa314SSam McCall   EXPECT_EQ(Vector->name(), "vector");
50d46d44e3SHaojian Wu   EXPECT_EQ(Vector->qualifiedName(), "std::vector");
5146a6f5aeSKirill Bobyrev   EXPECT_EQ(llvm::to_string(*Vector), "std::vector");
5246a6f5aeSKirill Bobyrev   EXPECT_FALSE(stdlib::Symbol::named("std::", "dongle"));
5346a6f5aeSKirill Bobyrev   EXPECT_FALSE(stdlib::Symbol::named("clang::", "ASTContext"));
5446a6f5aeSKirill Bobyrev 
551285172cSViktoriia Bakalova   EXPECT_TRUE(stdlib::Symbol::named("std::", "vector", stdlib::Lang::CXX));
561285172cSViktoriia Bakalova   EXPECT_FALSE(stdlib::Symbol::named("std::", "vector", stdlib::Lang::C));
571285172cSViktoriia Bakalova 
5846a6f5aeSKirill Bobyrev   EXPECT_EQ(Vector->header(), *VectorH);
5946a6f5aeSKirill Bobyrev   EXPECT_THAT(Vector->headers(), ElementsAre(*VectorH));
60e1aaa314SSam McCall 
615a623c2aSKadir Cetinkaya   EXPECT_TRUE(stdlib::Symbol::named("std::", "get"));
625a623c2aSKadir Cetinkaya   EXPECT_FALSE(stdlib::Symbol::named("std::", "get")->header());
635a623c2aSKadir Cetinkaya 
643599cbd3SHaojian Wu   EXPECT_THAT(stdlib::Symbol::named("std::", "basic_iostream")->headers(),
653599cbd3SHaojian Wu               ElementsAre(stdlib::Header::named("<istream>"),
663599cbd3SHaojian Wu                           stdlib::Header::named("<iostream>"),
673599cbd3SHaojian Wu                           stdlib::Header::named("<iosfwd>")));
6811dcd885SHaojian Wu   EXPECT_THAT(stdlib::Symbol::named("std::", "size_t")->headers(),
6911dcd885SHaojian Wu               ElementsAre(stdlib::Header::named("<cstddef>"),
7011dcd885SHaojian Wu                           stdlib::Header::named("<cstdlib>"),
7111dcd885SHaojian Wu                           stdlib::Header::named("<cstring>"),
7211dcd885SHaojian Wu                           stdlib::Header::named("<cwchar>"),
7311dcd885SHaojian Wu                           stdlib::Header::named("<cuchar>"),
7411dcd885SHaojian Wu                           stdlib::Header::named("<ctime>"),
7511dcd885SHaojian Wu                           stdlib::Header::named("<cstdio>")));
7611dcd885SHaojian Wu   EXPECT_EQ(stdlib::Symbol::named("std::", "size_t")->header(),
7711dcd885SHaojian Wu             stdlib::Header::named("<cstddef>"));
783599cbd3SHaojian Wu 
79e1aaa314SSam McCall   EXPECT_THAT(stdlib::Header::all(), Contains(*VectorH));
80e1aaa314SSam McCall   EXPECT_THAT(stdlib::Symbol::all(), Contains(*Vector));
81c812ab73SHaojian Wu   EXPECT_TRUE(stdlib::Header::named("<stdint.h>", stdlib::Lang::CXX));
82c812ab73SHaojian Wu   EXPECT_FALSE(stdlib::Header::named("<ios646.h>", stdlib::Lang::CXX));
83c812ab73SHaojian Wu }
841285172cSViktoriia Bakalova 
TEST(StdlibTest,Experimental)85d4021ed3SYounan Zhang TEST(StdlibTest, Experimental) {
86d4021ed3SYounan Zhang   EXPECT_FALSE(
87d4021ed3SYounan Zhang       stdlib::Header::named("<experimental/filesystem>", stdlib::Lang::C));
88d4021ed3SYounan Zhang   EXPECT_TRUE(
89d4021ed3SYounan Zhang       stdlib::Header::named("<experimental/filesystem>", stdlib::Lang::CXX));
90d4021ed3SYounan Zhang 
91d4021ed3SYounan Zhang   auto Symbol = stdlib::Symbol::named("std::experimental::filesystem::",
92d4021ed3SYounan Zhang                                       "system_complete");
93d4021ed3SYounan Zhang   EXPECT_TRUE(Symbol);
94d4021ed3SYounan Zhang   EXPECT_EQ(Symbol->scope(), "std::experimental::filesystem::");
95d4021ed3SYounan Zhang   EXPECT_EQ(Symbol->name(), "system_complete");
96d4021ed3SYounan Zhang   EXPECT_EQ(Symbol->header(),
97d4021ed3SYounan Zhang             stdlib::Header::named("<experimental/filesystem>"));
98d4021ed3SYounan Zhang   EXPECT_EQ(Symbol->qualifiedName(),
99d4021ed3SYounan Zhang             "std::experimental::filesystem::system_complete");
100d4021ed3SYounan Zhang }
101d4021ed3SYounan Zhang 
TEST(StdlibTest,CCompat)102c812ab73SHaojian Wu TEST(StdlibTest, CCompat) {
103c812ab73SHaojian Wu   EXPECT_THAT(
104c812ab73SHaojian Wu       stdlib::Symbol::named("", "int16_t", stdlib::Lang::CXX)->headers(),
105c812ab73SHaojian Wu       ElementsAre(stdlib::Header::named("<cstdint>"),
106c812ab73SHaojian Wu                   stdlib::Header::named("<stdint.h>")));
107c812ab73SHaojian Wu   EXPECT_THAT(
108c812ab73SHaojian Wu       stdlib::Symbol::named("std::", "int16_t", stdlib::Lang::CXX)->headers(),
109c812ab73SHaojian Wu       ElementsAre(stdlib::Header::named("<cstdint>")));
110c812ab73SHaojian Wu 
111c812ab73SHaojian Wu   EXPECT_TRUE(stdlib::Header::named("<stdint.h>", stdlib::Lang::C));
112c812ab73SHaojian Wu   EXPECT_THAT(
113c812ab73SHaojian Wu       stdlib::Symbol::named("", "int16_t", stdlib::Lang::C)->headers(),
114c812ab73SHaojian Wu       ElementsAre(stdlib::Header::named("<stdint.h>", stdlib::Lang::C)));
115c812ab73SHaojian Wu   EXPECT_FALSE(stdlib::Symbol::named("std::", "int16_t", stdlib::Lang::C));
11646a6f5aeSKirill Bobyrev }
11746a6f5aeSKirill Bobyrev 
TEST(StdlibTest,Recognizer)11846a6f5aeSKirill Bobyrev TEST(StdlibTest, Recognizer) {
119a7691deeSSam McCall   TestAST AST(R"cpp(
12046a6f5aeSKirill Bobyrev     namespace std {
12146a6f5aeSKirill Bobyrev     inline namespace inl {
12246a6f5aeSKirill Bobyrev 
12346a6f5aeSKirill Bobyrev     template <typename>
12446a6f5aeSKirill Bobyrev     struct vector { class nested {}; };
12546a6f5aeSKirill Bobyrev 
12646a6f5aeSKirill Bobyrev     class secret {};
12746a6f5aeSKirill Bobyrev 
12846a6f5aeSKirill Bobyrev     } // inl
12946a6f5aeSKirill Bobyrev 
13046a6f5aeSKirill Bobyrev     inline namespace __1 {
13146a6f5aeSKirill Bobyrev       namespace chrono {
13246a6f5aeSKirill Bobyrev         inline namespace chrono_inl {
13346a6f5aeSKirill Bobyrev         class system_clock {};
13446a6f5aeSKirill Bobyrev         } // chrono_inl
13546a6f5aeSKirill Bobyrev       } // chrono
13646a6f5aeSKirill Bobyrev     } // __1
13746a6f5aeSKirill Bobyrev 
13846a6f5aeSKirill Bobyrev     } // std
13946a6f5aeSKirill Bobyrev 
14046a6f5aeSKirill Bobyrev     // C Standard Library structure defined in <stdlib.h>
14146a6f5aeSKirill Bobyrev     struct div_t {};
14246a6f5aeSKirill Bobyrev 
14346a6f5aeSKirill Bobyrev     class vector {};
14446a6f5aeSKirill Bobyrev     std::vector<int> vec;
14546a6f5aeSKirill Bobyrev     std::vector<int>::nested nest;
14646a6f5aeSKirill Bobyrev     std::secret sec;
14746a6f5aeSKirill Bobyrev     std::chrono::system_clock clock;
14846a6f5aeSKirill Bobyrev 
14946a6f5aeSKirill Bobyrev     div_t div;
15046a6f5aeSKirill Bobyrev   )cpp");
15146a6f5aeSKirill Bobyrev 
152a7691deeSSam McCall   auto &VectorNonstd = lookup(AST, "vector");
153a7691deeSSam McCall   auto *Vec = cast<VarDecl>(lookup(AST, "vec")).getType()->getAsCXXRecordDecl();
15446a6f5aeSKirill Bobyrev   auto *Nest =
155a7691deeSSam McCall       cast<VarDecl>(lookup(AST, "nest")).getType()->getAsCXXRecordDecl();
15646a6f5aeSKirill Bobyrev   auto *Clock =
157a7691deeSSam McCall       cast<VarDecl>(lookup(AST, "clock")).getType()->getAsCXXRecordDecl();
158a7691deeSSam McCall   auto *Sec = cast<VarDecl>(lookup(AST, "sec")).getType()->getAsCXXRecordDecl();
15946a6f5aeSKirill Bobyrev   auto *CDivT =
160a7691deeSSam McCall       cast<VarDecl>(lookup(AST, "div")).getType()->getAsCXXRecordDecl();
16146a6f5aeSKirill Bobyrev 
16246a6f5aeSKirill Bobyrev   stdlib::Recognizer Recognizer;
16346a6f5aeSKirill Bobyrev 
164a41fbb1fSKazu Hirata   EXPECT_EQ(Recognizer(&VectorNonstd), std::nullopt);
16546a6f5aeSKirill Bobyrev   EXPECT_EQ(Recognizer(Vec), stdlib::Symbol::named("std::", "vector"));
1661285172cSViktoriia Bakalova   EXPECT_EQ(Recognizer(Vec),
1671285172cSViktoriia Bakalova             stdlib::Symbol::named("std::", "vector", stdlib::Lang::CXX));
16846a6f5aeSKirill Bobyrev   EXPECT_EQ(Recognizer(Nest), stdlib::Symbol::named("std::", "vector"));
16946a6f5aeSKirill Bobyrev   EXPECT_EQ(Recognizer(Clock),
17046a6f5aeSKirill Bobyrev             stdlib::Symbol::named("std::chrono::", "system_clock"));
171c812ab73SHaojian Wu   auto DivT = stdlib::Symbol::named("", "div_t", stdlib::Lang::CXX);
172c812ab73SHaojian Wu   EXPECT_TRUE(DivT);
173c812ab73SHaojian Wu   EXPECT_EQ(Recognizer(CDivT), DivT);
174a41fbb1fSKazu Hirata   EXPECT_EQ(Recognizer(Sec), std::nullopt);
17546a6f5aeSKirill Bobyrev }
17646a6f5aeSKirill Bobyrev 
TEST(StdlibTest,RecognizerForC99)177e93cbd18SHaojian Wu TEST(StdlibTest, RecognizerForC99) {
178e93cbd18SHaojian Wu   TestInputs Input("typedef char uint8_t;");
179e93cbd18SHaojian Wu   Input.Language = TestLanguage::Lang_C99;
180e93cbd18SHaojian Wu   TestAST AST(Input);
181e93cbd18SHaojian Wu 
182e93cbd18SHaojian Wu   auto &Uint8T = lookup(AST, "uint8_t");
183e93cbd18SHaojian Wu   stdlib::Recognizer Recognizer;
184e93cbd18SHaojian Wu   EXPECT_EQ(Recognizer(&Uint8T),
185e93cbd18SHaojian Wu             stdlib::Symbol::named("", "uint8_t", stdlib::Lang::C));
186e93cbd18SHaojian Wu }
187e93cbd18SHaojian Wu 
TEST(StdlibTest,SpecialCMappings)188*756c2056Skadir çetinkaya TEST(StdlibTest, SpecialCMappings) {
189*756c2056Skadir çetinkaya   TestInputs Input("typedef char size_t;");
190*756c2056Skadir çetinkaya   Input.Language = TestLanguage::Lang_C99;
191*756c2056Skadir çetinkaya   TestAST AST(Input);
192*756c2056Skadir çetinkaya 
193*756c2056Skadir çetinkaya   auto &SizeT = lookup(AST, "size_t");
194*756c2056Skadir çetinkaya   stdlib::Recognizer Recognizer;
195*756c2056Skadir çetinkaya   auto ActualSym = Recognizer(&SizeT);
196*756c2056Skadir çetinkaya   assert(ActualSym);
197*756c2056Skadir çetinkaya   EXPECT_EQ(ActualSym, stdlib::Symbol::named("", "size_t", stdlib::Lang::C));
198*756c2056Skadir çetinkaya   EXPECT_EQ(ActualSym->header()->name(), "<stddef.h>");
199*756c2056Skadir çetinkaya }
200*756c2056Skadir çetinkaya 
20146a6f5aeSKirill Bobyrev } // namespace
20246a6f5aeSKirill Bobyrev } // namespace tooling
20346a6f5aeSKirill Bobyrev } // namespace clang
204