[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.
This commit is contained in:
Chuanqi Xu
2025-03-25 09:43:13 +08:00
committed by GitHub
parent 5be9082fed
commit e5f100676e
2 changed files with 41 additions and 1 deletions

View File

@@ -22,7 +22,9 @@ std::optional<Path> getCorrespondingHeaderOrSource(
PathRef OriginalFile, llvm::IntrusiveRefCntPtr<llvm::vfs::FileSystem> VFS) {
llvm::StringRef SourceExtensions[] = {".cpp", ".c", ".cc", ".cxx",
".c++", ".m", ".mm"};
llvm::StringRef HeaderExtensions[] = {".h", ".hh", ".hpp", ".hxx", ".inc"};
llvm::StringRef HeaderExtensions[] = {".h", ".hh", ".hpp", ".hxx",
".inc", ".cppm", ".ccm", ".cxxm",
".c++m", ".ixx"};
llvm::StringRef PathExt = llvm::sys::path::extension(OriginalFile);

View File

@@ -76,6 +76,44 @@ TEST(HeaderSourceSwitchTest, FileHeuristic) {
EXPECT_FALSE(PathResult.has_value());
}
TEST(HeaderSourceSwitchTest, ModuleInterfaces) {
MockFS FS;
auto FooCC = testPath("foo.cc");
auto FooCPPM = testPath("foo.cppm");
FS.Files[FooCC];
FS.Files[FooCPPM];
std::optional<Path> PathResult =
getCorrespondingHeaderOrSource(FooCC, FS.view(std::nullopt));
EXPECT_TRUE(PathResult.has_value());
ASSERT_EQ(*PathResult, FooCPPM);
auto Foo2CPP = testPath("foo2.cpp");
auto Foo2CCM = testPath("foo2.ccm");
FS.Files[Foo2CPP];
FS.Files[Foo2CCM];
PathResult = getCorrespondingHeaderOrSource(Foo2CPP, FS.view(std::nullopt));
EXPECT_TRUE(PathResult.has_value());
ASSERT_EQ(*PathResult, Foo2CCM);
auto Foo3CXX = testPath("foo3.cxx");
auto Foo3CXXM = testPath("foo3.cxxm");
FS.Files[Foo3CXX];
FS.Files[Foo3CXXM];
PathResult = getCorrespondingHeaderOrSource(Foo3CXX, FS.view(std::nullopt));
EXPECT_TRUE(PathResult.has_value());
ASSERT_EQ(*PathResult, Foo3CXXM);
auto Foo4CPLUSPLUS = testPath("foo4.c++");
auto Foo4CPLUSPLUSM = testPath("foo4.c++m");
FS.Files[Foo4CPLUSPLUS];
FS.Files[Foo4CPLUSPLUSM];
PathResult =
getCorrespondingHeaderOrSource(Foo4CPLUSPLUS, FS.view(std::nullopt));
EXPECT_TRUE(PathResult.has_value());
ASSERT_EQ(*PathResult, Foo4CPLUSPLUSM);
}
MATCHER_P(declNamed, Name, "") {
if (const NamedDecl *ND = dyn_cast<NamedDecl>(arg))
if (ND->getQualifiedNameAsString() == Name)