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 IntrusiveRefCntPtr
<DiagnosticsEngine
> Diags
=
61 CompilerInstance::createDiagnostics(new DiagnosticOptions());
62 CreateInvocationOptions CIOpts
;
64 CIOpts
.VFS
= llvm::vfs::createPhysicalFileSystem();
66 std::string CacheBMIPath
=
67 llvm::Twine(TestDir
+ "/" + ModuleName
+ ".pcm").str();
68 std::string PrebuiltModulePath
=
69 "-fprebuilt-module-path=" + TestDir
.str().str();
70 const char *Args
[] = {"clang++",
73 PrebuiltModulePath
.c_str(),
79 std::shared_ptr
<CompilerInvocation
> Invocation
=
80 createInvocation(Args
, CIOpts
);
81 EXPECT_TRUE(Invocation
);
83 CompilerInstance Instance
;
84 Instance
.setDiagnostics(Diags
.get());
85 Instance
.setInvocation(Invocation
);
86 Instance
.getFrontendOpts().OutputFile
= CacheBMIPath
;
87 GenerateReducedModuleInterfaceAction Action
;
88 EXPECT_TRUE(Instance
.ExecuteAction(Action
));
89 EXPECT_FALSE(Diags
->hasErrorOccurred());
95 struct TrivialVisibleDeclConsumer
: public VisibleDeclConsumer
{
96 TrivialVisibleDeclConsumer() {}
97 void EnteredContext(DeclContext
*Ctx
) override
{}
98 void FoundDecl(NamedDecl
*ND
, NamedDecl
*Hiding
, DeclContext
*Ctx
,
99 bool InBaseClass
) override
{
106 class NoloadLookupConsumer
: public SemaConsumer
{
108 void InitializeSema(Sema
&S
) override
{ SemaPtr
= &S
; }
110 bool HandleTopLevelDecl(DeclGroupRef D
) override
{
111 if (!D
.isSingleDecl())
114 Decl
*TD
= D
.getSingleDecl();
116 auto *ID
= dyn_cast
<ImportDecl
>(TD
);
120 clang::Module
*M
= ID
->getImportedModule();
125 auto *Std
= SemaPtr
->getStdNamespace();
127 TrivialVisibleDeclConsumer Consumer
;
128 SemaPtr
->LookupVisibleDecls(Std
, Sema::LookupNameKind::LookupOrdinaryName
,
130 /*IncludeGlobalScope=*/true,
131 /*IncludeDependentBases=*/false,
132 /*LoadExternal=*/false);
133 EXPECT_EQ(Consumer
.FoundNum
, 1);
138 Sema
*SemaPtr
= nullptr;
141 class NoloadLookupAction
: public ASTFrontendAction
{
142 std::unique_ptr
<ASTConsumer
>
143 CreateASTConsumer(CompilerInstance
&CI
, StringRef
/*Unused*/) override
{
144 return std::make_unique
<NoloadLookupConsumer
>();
148 TEST_F(NoloadLookupTest
, NonModulesTest
) {
149 GenerateModuleInterface("M", R
"cpp(
154 void bar(int x = What()) {
158 export using std::bar;
161 GenerateModuleInterface("R", R
"cpp(
171 const char *test_file_contents
= R
"cpp(
180 std::string DepArg
= "-fprebuilt-module-path=" + TestDir
.str().str();
181 EXPECT_TRUE(runToolOnCodeWithArgs(std::make_unique
<NoloadLookupAction
>(),