[clang][modules] Don't prevent translation of FW_Private includes when explicitly...
[llvm-project.git] / clang-tools-extra / clangd / unittests / ModulesTests.cpp
blob1a73f84ff63ceaddcbb80bf56f4f5936f68b4826
1 //===-- ModulesTests.cpp ---------------------------------------*- C++ -*-===//
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 //===----------------------------------------------------------------------===//
9 #include "TestFS.h"
10 #include "TestTU.h"
11 #include "llvm/ADT/StringRef.h"
12 #include "gmock/gmock.h"
13 #include "gtest/gtest.h"
15 #include <memory>
16 #include <string>
18 namespace clang {
19 namespace clangd {
20 namespace {
22 TEST(Modules, TextualIncludeInPreamble) {
23 TestTU TU = TestTU::withCode(R"cpp(
24 #include "Textual.h"
26 void foo() {}
27 )cpp");
28 TU.ExtraArgs.push_back("-fmodule-name=M");
29 TU.ExtraArgs.push_back("-fmodule-map-file=" + testPath("m.modulemap"));
30 TU.AdditionalFiles["Textual.h"] = "void foo();";
31 TU.AdditionalFiles["m.modulemap"] = R"modulemap(
32 module M {
33 module Textual {
34 textual header "Textual.h"
37 )modulemap";
38 // Test that we do not crash.
39 TU.index();
42 // Verify that visibility of AST nodes belonging to modules, but loaded from
43 // preamble PCH, is restored.
44 TEST(Modules, PreambleBuildVisibility) {
45 TestTU TU = TestTU::withCode(R"cpp(
46 #include "module.h"
48 foo x;
49 )cpp");
50 TU.OverlayRealFileSystemForModules = true;
51 TU.ExtraArgs.push_back("-fmodules");
52 TU.ExtraArgs.push_back("-fmodules-strict-decluse");
53 TU.ExtraArgs.push_back("-Xclang");
54 TU.ExtraArgs.push_back("-fmodules-local-submodule-visibility");
55 TU.ExtraArgs.push_back("-fmodule-map-file=" + testPath("m.modulemap"));
56 TU.AdditionalFiles["module.h"] = R"cpp(
57 typedef int foo;
58 )cpp";
59 TU.AdditionalFiles["m.modulemap"] = R"modulemap(
60 module M {
61 header "module.h"
63 )modulemap";
64 EXPECT_TRUE(TU.build().getDiagnostics().empty());
67 TEST(Modules, Diagnostic) {
68 // Produce a diagnostic while building an implicit module. Use
69 // -fmodules-strict-decluse, but any non-silenced diagnostic will do.
70 TestTU TU = TestTU::withCode(R"cpp(
71 /*error-ok*/
72 #include "modular.h"
74 void bar() {}
75 )cpp");
76 TU.OverlayRealFileSystemForModules = true;
77 TU.ExtraArgs.push_back("-fmodule-map-file=" + testPath("m.modulemap"));
78 TU.ExtraArgs.push_back("-fmodules");
79 TU.ExtraArgs.push_back("-fimplicit-modules");
80 TU.ExtraArgs.push_back("-fmodules-strict-decluse");
81 TU.AdditionalFiles["modular.h"] = R"cpp(
82 #include "non-modular.h"
83 )cpp";
84 TU.AdditionalFiles["non-modular.h"] = "";
85 TU.AdditionalFiles["m.modulemap"] = R"modulemap(
86 module M {
87 header "modular.h"
89 )modulemap";
91 // Test that we do not crash.
92 TU.build();
95 // Unknown module formats are a fatal failure for clang. Ensure we don't crash.
96 TEST(Modules, UnknownFormat) {
97 TestTU TU = TestTU::withCode(R"(#include "modular.h")");
98 TU.OverlayRealFileSystemForModules = true;
99 TU.ExtraArgs.push_back("-Xclang");
100 TU.ExtraArgs.push_back("-fmodule-format=obj");
101 TU.ExtraArgs.push_back("-fmodule-map-file=" + testPath("m.modulemap"));
102 TU.ExtraArgs.push_back("-fmodules");
103 TU.ExtraArgs.push_back("-fimplicit-modules");
104 TU.AdditionalFiles["modular.h"] = "";
105 TU.AdditionalFiles["m.modulemap"] = R"modulemap(
106 module M {
107 header "modular.h"
108 })modulemap";
110 // Test that we do not crash.
111 TU.build();
114 // Test that we can build and use a preamble for a module unit.
115 TEST(Modules, ModulePreamble) {
116 TestTU TU = TestTU::withCode(R"cpp(
117 module;
118 #define PREAMBLE_MACRO 1
119 export module foo;
120 #define MODULE_MACRO 2
121 module :private;
122 #define PRIVATE_MACRO 3
123 )cpp");
124 TU.ExtraArgs.push_back("-std=c++20");
125 TU.ExtraArgs.push_back("--precompile");
127 auto AST = TU.build();
128 auto &SM = AST.getSourceManager();
129 auto GetMacroFile = [&](llvm::StringRef Name) -> FileID {
130 if (auto *MI = AST.getPreprocessor().getMacroInfo(
131 &AST.getASTContext().Idents.get(Name)))
132 return SM.getFileID(MI->getDefinitionLoc());
133 return {};
136 EXPECT_EQ(GetMacroFile("PREAMBLE_MACRO"), SM.getPreambleFileID());
137 EXPECT_EQ(GetMacroFile("MODULE_MACRO"), SM.getMainFileID());
138 EXPECT_EQ(GetMacroFile("PRIVATE_MACRO"), SM.getMainFileID());
141 } // namespace
142 } // namespace clangd
143 } // namespace clang