Skip to content

Commit e5f1006

Browse files
authored
[clangd] [C++20] [Modules] Add modules suffix for 'Header' Source Switch (#131591)
Support the trivial "header"/source switch for module interfaces. I initially thought the naming are bad and we should rename it. But later I feel it is better to split patches as much as possible. From the codes it looks like there are problems. e.g., `isHeaderFile`. But let's try to fix them in different patches.
1 parent 5be9082 commit e5f1006

File tree

2 files changed

+41
-1
lines changed

2 files changed

+41
-1
lines changed

clang-tools-extra/clangd/HeaderSourceSwitch.cpp

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,9 @@ std::optional<Path> getCorrespondingHeaderOrSource(
2222
PathRef OriginalFile, llvm::IntrusiveRefCntPtr<llvm::vfs::FileSystem> VFS) {
2323
llvm::StringRef SourceExtensions[] = {".cpp", ".c", ".cc", ".cxx",
2424
".c++", ".m", ".mm"};
25-
llvm::StringRef HeaderExtensions[] = {".h", ".hh", ".hpp", ".hxx", ".inc"};
25+
llvm::StringRef HeaderExtensions[] = {".h", ".hh", ".hpp", ".hxx",
26+
".inc", ".cppm", ".ccm", ".cxxm",
27+
".c++m", ".ixx"};
2628

2729
llvm::StringRef PathExt = llvm::sys::path::extension(OriginalFile);
2830

clang-tools-extra/clangd/unittests/HeaderSourceSwitchTests.cpp

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -76,6 +76,44 @@ TEST(HeaderSourceSwitchTest, FileHeuristic) {
7676
EXPECT_FALSE(PathResult.has_value());
7777
}
7878

79+
TEST(HeaderSourceSwitchTest, ModuleInterfaces) {
80+
MockFS FS;
81+
82+
auto FooCC = testPath("foo.cc");
83+
auto FooCPPM = testPath("foo.cppm");
84+
FS.Files[FooCC];
85+
FS.Files[FooCPPM];
86+
std::optional<Path> PathResult =
87+
getCorrespondingHeaderOrSource(FooCC, FS.view(std::nullopt));
88+
EXPECT_TRUE(PathResult.has_value());
89+
ASSERT_EQ(*PathResult, FooCPPM);
90+
91+
auto Foo2CPP = testPath("foo2.cpp");
92+
auto Foo2CCM = testPath("foo2.ccm");
93+
FS.Files[Foo2CPP];
94+
FS.Files[Foo2CCM];
95+
PathResult = getCorrespondingHeaderOrSource(Foo2CPP, FS.view(std::nullopt));
96+
EXPECT_TRUE(PathResult.has_value());
97+
ASSERT_EQ(*PathResult, Foo2CCM);
98+
99+
auto Foo3CXX = testPath("foo3.cxx");
100+
auto Foo3CXXM = testPath("foo3.cxxm");
101+
FS.Files[Foo3CXX];
102+
FS.Files[Foo3CXXM];
103+
PathResult = getCorrespondingHeaderOrSource(Foo3CXX, FS.view(std::nullopt));
104+
EXPECT_TRUE(PathResult.has_value());
105+
ASSERT_EQ(*PathResult, Foo3CXXM);
106+
107+
auto Foo4CPLUSPLUS = testPath("foo4.c++");
108+
auto Foo4CPLUSPLUSM = testPath("foo4.c++m");
109+
FS.Files[Foo4CPLUSPLUS];
110+
FS.Files[Foo4CPLUSPLUSM];
111+
PathResult =
112+
getCorrespondingHeaderOrSource(Foo4CPLUSPLUS, FS.view(std::nullopt));
113+
EXPECT_TRUE(PathResult.has_value());
114+
ASSERT_EQ(*PathResult, Foo4CPLUSPLUSM);
115+
}
116+
79117
MATCHER_P(declNamed, Name, "") {
80118
if (const NamedDecl *ND = dyn_cast<NamedDecl>(arg))
81119
if (ND->getQualifiedNameAsString() == Name)

0 commit comments

Comments
 (0)