Files
TheRock/compiler/amd-llvm/clang/unittests/Lex/ModuleMapTest.cpp
T
derek.holloway 7502bf64a4
CodeQL / Analyze (actions) (push) Canceled after 0s
CodeQL / Analyze (python) (push) Canceled after 0s
pre-commit / pre-commit (push) Canceled after 0s
Multi-Arch CI / setup (push) Canceled after 0s
Publish build_manylinux_x86_64 images / publish_build_manylinux_x86_64 (push) Canceled after 0s
Setup (Multi-Arch) / setup (push) Canceled after 0s
Multi-Arch CI / Linux::${{ fromJSON(needs.setup.outputs.linux_build_config || '{}').build_variant_label || 'skip' }} (push) Canceled after 0s
Publish TheRock Docker image / build-and-push-image (push) Canceled after 0s
Publish no_rocm_image_ubi10 image / publish_no_rocm_image_ubi10 (push) Canceled after 0s
Multi-Arch CI / Windows::${{ fromJSON(needs.setup.outputs.windows_build_config || '{}').build_variant_label || 'skip' }} (push) Canceled after 0s
Publish TheRock Docker image / build-and-push-image (push) Canceled after 0s
Multi-Arch CI / Manifest Diff (push) Canceled after 0s
TheRock Manifest Diff Report / Generate Manifest Diff Report (push) Canceled after 0s
Multi-Arch CI / CI Summary (push) Canceled after 0s
Publish no_rocm_image_ubuntu24_04 images / publish_no_rocm_image_ubuntu24_04 (push) Canceled after 0s
Publish no_rocm_image_ubuntu24_04_ocl_rt images / publish_no_rocm_image_ubuntu24_04_ocl_rt (push) Canceled after 0s
Publish TheRock Docker image / build-and-push-image (push) Canceled after 0s
Publish TheRock Docker image / build-and-push-image (push) Canceled after 0s
Publish no_rocm_image_ubuntu24_04 images / publish_no_rocm_image_ubuntu24_04_rocgdb (push) Canceled after 0s
Publish no_rocm_image_ubuntu24_04_rocgdb images / publish_no_rocm_image_ubuntu24_04_rocgdb (push) Canceled after 0s
Publish no_rocm_image_ubuntu24_04 images / publish_no_rocm_image_ubuntu24_04_ocl_rt (push) Canceled after 0s
Publish TheRock Docker image / build-and-push-image (push) Canceled after 0s
Unit Tests / Unit Tests :: ubuntu-24.04 (push) Canceled after 0s
Unit Tests / Unit Tests :: windows-2022 (push) Canceled after 0s
Publish no_rocm_image_ubuntu24_04 images / publish_no_rocm_image_ubuntu24_04_media (push) Canceled after 0s
Unit Tests / Unit Tests Summary (push) Canceled after 0s
Publish no_rocm_image_ubuntu24_04 images / publish_no_rocm_image_ubuntu24_04_openmpi (push) Canceled after 0s
Flatten subprojects into a single base monorepo
2026-09-02 16:34:47 -07:00

132 lines
4.3 KiB
C++

//===- unittests/Lex/ModuleMapTest.cpp - PPCallbacks tests ------===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===--------------------------------------------------------------===//
//
#include "clang/Lex/ModuleMap.h"
#include "clang/Basic/SourceManager.h"
#include "clang/Basic/TargetInfo.h"
#include "clang/Basic/TargetOptions.h"
#include "clang/Lex/HeaderSearch.h"
#include "clang/Lex/HeaderSearchOptions.h"
#include "llvm/Support/Path.h"
#include "llvm/Support/VirtualFileSystem.h"
#include "gtest/gtest.h"
#include <vector>
namespace clang {
namespace {
struct InterceptorFS : llvm::vfs::ProxyFileSystem {
// Record the paths looked up by a ModuleMap.
std::vector<std::string> StatPaths;
InterceptorFS(IntrusiveRefCntPtr<llvm::vfs::FileSystem> UnderlyingFS)
: ProxyFileSystem(UnderlyingFS) {}
llvm::ErrorOr<llvm::vfs::Status> status(const Twine &Path) override {
StatPaths.emplace_back(Path.str());
return ProxyFileSystem::status(Path);
}
};
class ModuleMapTest : public ::testing::Test {
protected:
ModuleMapTest()
: InMemFS(llvm::makeIntrusiveRefCnt<llvm::vfs::InMemoryFileSystem>()),
VFS(llvm::makeIntrusiveRefCnt<InterceptorFS>(InMemFS)),
FileMgr(FileMgrOpts, VFS),
Diagnostics(DiagnosticIDs::create(), DiagnosticOpts,
new IgnoringDiagConsumer()),
SrcMgr(Diagnostics, FileMgr), TargetOpts(new TargetOptions),
HdrSearch(HdrSearchOpts, SrcMgr, Diagnostics, LangOpts,
/* Target = */ nullptr),
Map(SrcMgr, Diagnostics, LangOpts, /* Target= */ nullptr, HdrSearch) {
TargetOpts->Triple = "x86_64-apple-darwin11.1.0";
Target = TargetInfo::CreateTargetInfo(Diagnostics, *TargetOpts);
Map.setTarget(*Target);
}
void addFile(llvm::StringRef Path, llvm::StringRef Content) {
InMemFS->addFile(Path, 0, llvm::MemoryBuffer::getMemBufferCopy(Content));
}
bool loadRoot(llvm::StringRef Path) {
auto File = FileMgr.getOptionalFileRef(Path);
if (!File) {
// parseAndLoadModuleMapFile returns false on success, true on error.
return true;
}
return Map.parseAndLoadModuleMapFile(*File, /* IsSystem = */ false,
/* ImplicitlyDiscovered = */ false,
File->getDir());
}
IntrusiveRefCntPtr<llvm::vfs::InMemoryFileSystem> InMemFS;
IntrusiveRefCntPtr<InterceptorFS> VFS;
FileSystemOptions FileMgrOpts;
FileManager FileMgr;
DiagnosticOptions DiagnosticOpts;
DiagnosticsEngine Diagnostics;
SourceManager SrcMgr;
LangOptions LangOpts;
std::shared_ptr<TargetOptions> TargetOpts;
llvm::IntrusiveRefCntPtr<TargetInfo> Target;
HeaderSearchOptions HdrSearchOpts;
HeaderSearch HdrSearch;
ModuleMap Map;
};
// Regression test for
// https://github.com/llvm/llvm-project/issues/147220.
//
// These tests specifically aim to validate that ModuleMap paths do not grow
// in an unbounded fashion in the presence of chained relative paths to extern
// modules.
//
TEST_F(ModuleMapTest, ExternModuleRelativeLookupPathIsNormalized) {
// Root module as entry point, chained extern module references:
// A -> B -> C
addFile("/root/A.cppmap", R"(
module A {}
extern module B "../root/B.cppmap"
)");
addFile("/root/B.cppmap", R"(
module B {}
extern module C "../root/C.cppmap"
)");
// Leaf module
addFile("/root/C.cppmap", "module C {}");
ASSERT_FALSE(loadRoot("/root/A.cppmap"));
// Now check paths used are normalised.
llvm::SmallSet<llvm::StringRef, 4> Seen;
for (const std::string &Path : VFS->StatPaths) {
llvm::StringRef BaseName;
for (llvm::StringRef Component : llvm::make_range(
llvm::sys::path::begin(Path), llvm::sys::path::end(Path))) {
// As `/root/A.cppmap` is absolute, there should be no relative paths at
// lookup time.
EXPECT_NE(Component, "..");
// Last component is basename
BaseName = Component;
}
Seen.insert(BaseName);
}
// Ensure the path check covered all the modules we expected.
ASSERT_TRUE(Seen.contains("A.cppmap"));
ASSERT_TRUE(Seen.contains("B.cppmap"));
ASSERT_TRUE(Seen.contains("C.cppmap"));
}
} // namespace
} // namespace clang