mirror of
https://github.com/capstone-engine/llvm-capstone.git
synced 2025-04-09 01:11:53 +00:00

Mixed path separators (ie, both / and \\) can mess up the sort order of the VFS map when dumping module dependencies, as was recently exposed by r224055 and papered over in r224145. Instead, we should simply use native paths for consistency. This also adds a TODO to add handling of .. in paths. There was some code for this before r224055, but it was untested and probably broken. llvm-svn: 224164
94 lines
3.0 KiB
C++
94 lines
3.0 KiB
C++
//===--- ModuleDependencyCollector.cpp - Collect module dependencies ------===//
|
|
//
|
|
// The LLVM Compiler Infrastructure
|
|
//
|
|
// This file is distributed under the University of Illinois Open Source
|
|
// License. See LICENSE.TXT for details.
|
|
//
|
|
//===----------------------------------------------------------------------===//
|
|
//
|
|
// Collect the dependencies of a set of modules.
|
|
//
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
#include "clang/Frontend/Utils.h"
|
|
#include "clang/Serialization/ASTReader.h"
|
|
#include "llvm/ADT/iterator_range.h"
|
|
#include "llvm/ADT/StringSet.h"
|
|
#include "llvm/Support/FileSystem.h"
|
|
#include "llvm/Support/Path.h"
|
|
#include "llvm/Support/raw_ostream.h"
|
|
|
|
using namespace clang;
|
|
|
|
namespace {
|
|
/// Private implementation for ModuleDependencyCollector
|
|
class ModuleDependencyListener : public ASTReaderListener {
|
|
ModuleDependencyCollector &Collector;
|
|
|
|
std::error_code copyToRoot(StringRef Src);
|
|
public:
|
|
ModuleDependencyListener(ModuleDependencyCollector &Collector)
|
|
: Collector(Collector) {}
|
|
bool needsInputFileVisitation() override { return true; }
|
|
bool needsSystemInputFileVisitation() override { return true; }
|
|
bool visitInputFile(StringRef Filename, bool IsSystem,
|
|
bool IsOverridden) override;
|
|
};
|
|
}
|
|
|
|
void ModuleDependencyCollector::attachToASTReader(ASTReader &R) {
|
|
R.addListener(llvm::make_unique<ModuleDependencyListener>(*this));
|
|
}
|
|
|
|
void ModuleDependencyCollector::writeFileMap() {
|
|
if (Seen.empty())
|
|
return;
|
|
|
|
SmallString<256> Dest = getDest();
|
|
llvm::sys::path::append(Dest, "vfs.yaml");
|
|
|
|
std::error_code EC;
|
|
llvm::raw_fd_ostream OS(Dest, EC, llvm::sys::fs::F_Text);
|
|
if (EC) {
|
|
setHasErrors();
|
|
return;
|
|
}
|
|
VFSWriter.write(OS);
|
|
}
|
|
|
|
std::error_code ModuleDependencyListener::copyToRoot(StringRef Src) {
|
|
using namespace llvm::sys;
|
|
|
|
// We need an absolute path to append to the root.
|
|
SmallString<256> AbsoluteSrc = Src;
|
|
fs::make_absolute(AbsoluteSrc);
|
|
// Canonicalize to a native path to avoid mixed separator styles.
|
|
path::native(AbsoluteSrc);
|
|
// TODO: We probably need to handle .. as well as . in order to have valid
|
|
// input to the YAMLVFSWriter.
|
|
FileManager::removeDotPaths(AbsoluteSrc);
|
|
|
|
// Build the destination path.
|
|
SmallString<256> Dest = Collector.getDest();
|
|
path::append(Dest, path::relative_path(AbsoluteSrc));
|
|
|
|
// Copy the file into place.
|
|
if (std::error_code EC = fs::create_directories(path::parent_path(Dest),
|
|
/*IgnoreExisting=*/true))
|
|
return EC;
|
|
if (std::error_code EC = fs::copy_file(AbsoluteSrc.str(), Dest.str()))
|
|
return EC;
|
|
// Use the absolute path under the root for the file mapping.
|
|
Collector.addFileMapping(AbsoluteSrc.str(), Dest.str());
|
|
return std::error_code();
|
|
}
|
|
|
|
bool ModuleDependencyListener::visitInputFile(StringRef Filename, bool IsSystem,
|
|
bool IsOverridden) {
|
|
if (Collector.insertSeen(Filename))
|
|
if (copyToRoot(Filename))
|
|
Collector.setHasErrors();
|
|
return true;
|
|
}
|