1 //== unittests/Sema/SemaNoloadLookupTest.cpp -------------------------========//
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
7 //===----------------------------------------------------------------------===//
9 #include "clang/AST/DeclLookups.h"
10 #include "clang/AST/DeclarationName.h"
11 #include "clang/ASTMatchers/ASTMatchFinder.h"
12 #include "clang/ASTMatchers/ASTMatchers.h"
13 #include "clang/Frontend/CompilerInstance.h"
14 #include "clang/Frontend/FrontendAction.h"
15 #include "clang/Frontend/FrontendActions.h"
16 #include "clang/Parse/ParseAST.h"
17 #include "clang/Sema/Lookup.h"
18 #include "clang/Sema/Sema.h"
19 #include "clang/Sema/SemaConsumer.h"
20 #include "clang/Tooling/Tooling.h"
21 #include "gtest/gtest.h"
24 using namespace clang
;
25 using namespace clang::tooling
;
29 class NoloadLookupTest
: public ::testing::Test
{
30 void SetUp() override
{
32 sys::fs::createUniqueDirectory("modules-no-comments-test", TestDir
));
35 void TearDown() override
{ sys::fs::remove_directories(TestDir
); }
38 SmallString
<256> TestDir
;
40 void addFile(StringRef Path
, StringRef Contents
) {
41 ASSERT_FALSE(sys::path::is_absolute(Path
));
43 SmallString
<256> AbsPath(TestDir
);
44 sys::path::append(AbsPath
, Path
);
47 sys::fs::create_directories(llvm::sys::path::parent_path(AbsPath
)));
50 llvm::raw_fd_ostream
OS(AbsPath
, EC
);
55 std::string
GenerateModuleInterface(StringRef ModuleName
,
57 std::string FileName
= llvm::Twine(ModuleName
+ ".cppm").str();
58 addFile(FileName
, Contents
);
60 CreateInvocationOptions CIOpts
;
61 CIOpts
.VFS
= llvm::vfs::createPhysicalFileSystem();
62 IntrusiveRefCntPtr
<DiagnosticsEngine
> Diags
=
63 CompilerInstance::createDiagnostics(*CIOpts
.VFS
,
64 new DiagnosticOptions());
67 std::string CacheBMIPath
=
68 llvm::Twine(TestDir
+ "/" + ModuleName
+ ".pcm").str();
69 std::string PrebuiltModulePath
=
70 "-fprebuilt-module-path=" + TestDir
.str().str();
71 const char *Args
[] = {"clang++",
74 PrebuiltModulePath
.c_str(),
80 std::shared_ptr
<CompilerInvocation
> Invocation
=
81 createInvocation(Args
, CIOpts
);
82 EXPECT_TRUE(Invocation
);
84 CompilerInstance Instance
;
85 Instance
.setDiagnostics(Diags
.get());
86 Instance
.setInvocation(Invocation
);
87 Instance
.getFrontendOpts().OutputFile
= CacheBMIPath
;
88 GenerateReducedModuleInterfaceAction Action
;
89 EXPECT_TRUE(Instance
.ExecuteAction(Action
));
90 EXPECT_FALSE(Diags
->hasErrorOccurred());
96 struct TrivialVisibleDeclConsumer
: public VisibleDeclConsumer
{
97 TrivialVisibleDeclConsumer() {}
98 void EnteredContext(DeclContext
*Ctx
) override
{}
99 void FoundDecl(NamedDecl
*ND
, NamedDecl
*Hiding
, DeclContext
*Ctx
,
100 bool InBaseClass
) override
{
107 class NoloadLookupConsumer
: public SemaConsumer
{
109 void InitializeSema(Sema
&S
) override
{ SemaPtr
= &S
; }
111 bool HandleTopLevelDecl(DeclGroupRef D
) override
{
112 if (!D
.isSingleDecl())
115 Decl
*TD
= D
.getSingleDecl();
117 auto *ID
= dyn_cast
<ImportDecl
>(TD
);
121 clang::Module
*M
= ID
->getImportedModule();
126 auto *Std
= SemaPtr
->getStdNamespace();
128 TrivialVisibleDeclConsumer Consumer
;
129 SemaPtr
->LookupVisibleDecls(Std
, Sema::LookupNameKind::LookupOrdinaryName
,
131 /*IncludeGlobalScope=*/true,
132 /*IncludeDependentBases=*/false,
133 /*LoadExternal=*/false);
134 EXPECT_EQ(Consumer
.FoundNum
, 1);
139 Sema
*SemaPtr
= nullptr;
142 class NoloadLookupAction
: public ASTFrontendAction
{
143 std::unique_ptr
<ASTConsumer
>
144 CreateASTConsumer(CompilerInstance
&CI
, StringRef
/*Unused*/) override
{
145 return std::make_unique
<NoloadLookupConsumer
>();
149 TEST_F(NoloadLookupTest
, NonModulesTest
) {
150 GenerateModuleInterface("M", R
"cpp(
155 void bar(int x = What()) {
159 export using std::bar;
162 GenerateModuleInterface("R", R
"cpp(
172 const char *test_file_contents
= R
"cpp(
181 std::string DepArg
= "-fprebuilt-module-path=" + TestDir
.str().str();
182 EXPECT_TRUE(runToolOnCodeWithArgs(std::make_unique
<NoloadLookupAction
>(),