Use FileEntryRef for PPCallbacks::FileSkipped
This fixes the issue where a filename dependendency was missing if the file that was skipped was included through a symlink in an earlier run, if the file manager was reused between runs. llvm-svn: 369998
This commit is contained in:
parent
228ffac678
commit
67d25fede9
|
@ -268,7 +268,9 @@ private:
|
||||||
FilenameTok.getEndLoc()),
|
FilenameTok.getEndLoc()),
|
||||||
File, "SearchPath", "RelPath", /*Imported=*/nullptr, Inc.FileKind);
|
File, "SearchPath", "RelPath", /*Imported=*/nullptr, Inc.FileKind);
|
||||||
if (File)
|
if (File)
|
||||||
Delegate->FileSkipped(*File, FilenameTok, Inc.FileKind);
|
// FIXME: Use correctly named FileEntryRef.
|
||||||
|
Delegate->FileSkipped(FileEntryRef(File->getName(), *File), FilenameTok,
|
||||||
|
Inc.FileKind);
|
||||||
else {
|
else {
|
||||||
llvm::SmallString<1> UnusedRecovery;
|
llvm::SmallString<1> UnusedRecovery;
|
||||||
Delegate->FileNotFound(WrittenFilename, UnusedRecovery);
|
Delegate->FileNotFound(WrittenFilename, UnusedRecovery);
|
||||||
|
|
|
@ -112,11 +112,11 @@ void PPCallbacksTracker::FileChanged(SourceLocation Loc,
|
||||||
|
|
||||||
// Callback invoked whenever a source file is skipped as the result
|
// Callback invoked whenever a source file is skipped as the result
|
||||||
// of header guard optimization.
|
// of header guard optimization.
|
||||||
void PPCallbacksTracker::FileSkipped(const FileEntry &SkippedFile,
|
void PPCallbacksTracker::FileSkipped(const FileEntryRef &SkippedFile,
|
||||||
const Token &FilenameTok,
|
const Token &FilenameTok,
|
||||||
SrcMgr::CharacteristicKind FileType) {
|
SrcMgr::CharacteristicKind FileType) {
|
||||||
beginCallback("FileSkipped");
|
beginCallback("FileSkipped");
|
||||||
appendArgument("ParentFile", &SkippedFile);
|
appendArgument("ParentFile", &SkippedFile.getFileEntry());
|
||||||
appendArgument("FilenameTok", FilenameTok);
|
appendArgument("FilenameTok", FilenameTok);
|
||||||
appendArgument("FileType", FileType, CharacteristicKindStrings);
|
appendArgument("FileType", FileType, CharacteristicKindStrings);
|
||||||
}
|
}
|
||||||
|
|
|
@ -89,7 +89,7 @@ public:
|
||||||
void FileChanged(SourceLocation Loc, PPCallbacks::FileChangeReason Reason,
|
void FileChanged(SourceLocation Loc, PPCallbacks::FileChangeReason Reason,
|
||||||
SrcMgr::CharacteristicKind FileType,
|
SrcMgr::CharacteristicKind FileType,
|
||||||
FileID PrevFID = FileID()) override;
|
FileID PrevFID = FileID()) override;
|
||||||
void FileSkipped(const FileEntry &SkippedFile, const Token &FilenameTok,
|
void FileSkipped(const FileEntryRef &SkippedFile, const Token &FilenameTok,
|
||||||
SrcMgr::CharacteristicKind FileType) override;
|
SrcMgr::CharacteristicKind FileType) override;
|
||||||
bool FileNotFound(llvm::StringRef FileName,
|
bool FileNotFound(llvm::StringRef FileName,
|
||||||
llvm::SmallVectorImpl<char> &RecoveryPath) override;
|
llvm::SmallVectorImpl<char> &RecoveryPath) override;
|
||||||
|
|
|
@ -57,10 +57,9 @@ public:
|
||||||
/// \param FilenameTok The file name token in \#include "FileName" directive
|
/// \param FilenameTok The file name token in \#include "FileName" directive
|
||||||
/// or macro expanded file name token from \#include MACRO(PARAMS) directive.
|
/// or macro expanded file name token from \#include MACRO(PARAMS) directive.
|
||||||
/// Note that FilenameTok contains corresponding quotes/angles symbols.
|
/// Note that FilenameTok contains corresponding quotes/angles symbols.
|
||||||
virtual void FileSkipped(const FileEntry &SkippedFile,
|
virtual void FileSkipped(const FileEntryRef &SkippedFile,
|
||||||
const Token &FilenameTok,
|
const Token &FilenameTok,
|
||||||
SrcMgr::CharacteristicKind FileType) {
|
SrcMgr::CharacteristicKind FileType) {}
|
||||||
}
|
|
||||||
|
|
||||||
/// Callback invoked whenever an inclusion directive results in a
|
/// Callback invoked whenever an inclusion directive results in a
|
||||||
/// file-not-found error.
|
/// file-not-found error.
|
||||||
|
@ -390,8 +389,7 @@ public:
|
||||||
Second->FileChanged(Loc, Reason, FileType, PrevFID);
|
Second->FileChanged(Loc, Reason, FileType, PrevFID);
|
||||||
}
|
}
|
||||||
|
|
||||||
void FileSkipped(const FileEntry &SkippedFile,
|
void FileSkipped(const FileEntryRef &SkippedFile, const Token &FilenameTok,
|
||||||
const Token &FilenameTok,
|
|
||||||
SrcMgr::CharacteristicKind FileType) override {
|
SrcMgr::CharacteristicKind FileType) override {
|
||||||
First->FileSkipped(SkippedFile, FilenameTok, FileType);
|
First->FileSkipped(SkippedFile, FilenameTok, FileType);
|
||||||
Second->FileSkipped(SkippedFile, FilenameTok, FileType);
|
Second->FileSkipped(SkippedFile, FilenameTok, FileType);
|
||||||
|
|
|
@ -59,7 +59,7 @@ struct DepCollectorPPCallbacks : public PPCallbacks {
|
||||||
/*IsModuleFile*/false, /*IsMissing*/false);
|
/*IsModuleFile*/false, /*IsMissing*/false);
|
||||||
}
|
}
|
||||||
|
|
||||||
void FileSkipped(const FileEntry &SkippedFile, const Token &FilenameTok,
|
void FileSkipped(const FileEntryRef &SkippedFile, const Token &FilenameTok,
|
||||||
SrcMgr::CharacteristicKind FileType) override {
|
SrcMgr::CharacteristicKind FileType) override {
|
||||||
StringRef Filename =
|
StringRef Filename =
|
||||||
llvm::sys::path::remove_leading_dotslash(SkippedFile.getName());
|
llvm::sys::path::remove_leading_dotslash(SkippedFile.getName());
|
||||||
|
|
|
@ -70,7 +70,7 @@ private:
|
||||||
void FileChanged(SourceLocation Loc, FileChangeReason Reason,
|
void FileChanged(SourceLocation Loc, FileChangeReason Reason,
|
||||||
SrcMgr::CharacteristicKind FileType,
|
SrcMgr::CharacteristicKind FileType,
|
||||||
FileID PrevFID) override;
|
FileID PrevFID) override;
|
||||||
void FileSkipped(const FileEntry &SkippedFile, const Token &FilenameTok,
|
void FileSkipped(const FileEntryRef &SkippedFile, const Token &FilenameTok,
|
||||||
SrcMgr::CharacteristicKind FileType) override;
|
SrcMgr::CharacteristicKind FileType) override;
|
||||||
void InclusionDirective(SourceLocation HashLoc, const Token &IncludeTok,
|
void InclusionDirective(SourceLocation HashLoc, const Token &IncludeTok,
|
||||||
StringRef FileName, bool IsAngled,
|
StringRef FileName, bool IsAngled,
|
||||||
|
@ -169,8 +169,8 @@ void InclusionRewriter::FileChanged(SourceLocation Loc,
|
||||||
|
|
||||||
/// Called whenever an inclusion is skipped due to canonical header protection
|
/// Called whenever an inclusion is skipped due to canonical header protection
|
||||||
/// macros.
|
/// macros.
|
||||||
void InclusionRewriter::FileSkipped(const FileEntry &/*SkippedFile*/,
|
void InclusionRewriter::FileSkipped(const FileEntryRef & /*SkippedFile*/,
|
||||||
const Token &/*FilenameTok*/,
|
const Token & /*FilenameTok*/,
|
||||||
SrcMgr::CharacteristicKind /*FileType*/) {
|
SrcMgr::CharacteristicKind /*FileType*/) {
|
||||||
assert(LastInclusionLocation.isValid() &&
|
assert(LastInclusionLocation.isValid() &&
|
||||||
"A file, that wasn't found via an inclusion directive, was skipped");
|
"A file, that wasn't found via an inclusion directive, was skipped");
|
||||||
|
|
|
@ -2029,7 +2029,7 @@ Preprocessor::ImportAction Preprocessor::HandleHeaderIncludeOrImport(
|
||||||
RelativePath, Action == Import ? SuggestedModule.getModule() : nullptr,
|
RelativePath, Action == Import ? SuggestedModule.getModule() : nullptr,
|
||||||
FileCharacter);
|
FileCharacter);
|
||||||
if (Action == Skip && File)
|
if (Action == Skip && File)
|
||||||
Callbacks->FileSkipped(File->getFileEntry(), FilenameTok, FileCharacter);
|
Callbacks->FileSkipped(*File, FilenameTok, FileCharacter);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!File)
|
if (!File)
|
||||||
|
|
|
@ -37,7 +37,8 @@ public:
|
||||||
: DependencyFileGenerator(Opts), Deps(Deps) {}
|
: DependencyFileGenerator(Opts), Deps(Deps) {}
|
||||||
|
|
||||||
void finishedMainFile(DiagnosticsEngine &Diags) override {
|
void finishedMainFile(DiagnosticsEngine &Diags) override {
|
||||||
Deps = getDependencies();
|
auto NewDeps = getDependencies();
|
||||||
|
Deps.insert(Deps.end(), NewDeps.begin(), NewDeps.end());
|
||||||
}
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
@ -121,5 +122,44 @@ TEST(DependencyScanner, ScanDepsReuseFilemanager) {
|
||||||
EXPECT_EQ(Files.getNumUniqueRealFiles(), 2u);
|
EXPECT_EQ(Files.getNumUniqueRealFiles(), 2u);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
TEST(DependencyScanner, ScanDepsReuseFilemanagerSkippedFile) {
|
||||||
|
std::vector<std::string> Compilation = {"-c", "-E", "-MT", "test.cpp.o"};
|
||||||
|
StringRef CWD = "/root";
|
||||||
|
FixedCompilationDatabase CDB(CWD, Compilation);
|
||||||
|
|
||||||
|
auto VFS = new llvm::vfs::InMemoryFileSystem();
|
||||||
|
VFS->setCurrentWorkingDirectory(CWD);
|
||||||
|
auto Sept = llvm::sys::path::get_separator();
|
||||||
|
std::string HeaderPath = llvm::formatv("{0}root{0}header.h", Sept);
|
||||||
|
std::string SymlinkPath = llvm::formatv("{0}root{0}symlink.h", Sept);
|
||||||
|
std::string TestPath = llvm::formatv("{0}root{0}test.cpp", Sept);
|
||||||
|
std::string Test2Path = llvm::formatv("{0}root{0}test2.cpp", Sept);
|
||||||
|
|
||||||
|
VFS->addFile(HeaderPath, 0,
|
||||||
|
llvm::MemoryBuffer::getMemBuffer("#pragma once\n"));
|
||||||
|
VFS->addHardLink(SymlinkPath, HeaderPath);
|
||||||
|
VFS->addFile(TestPath, 0,
|
||||||
|
llvm::MemoryBuffer::getMemBuffer(
|
||||||
|
"#include \"header.h\"\n#include \"symlink.h\"\n"));
|
||||||
|
VFS->addFile(Test2Path, 0,
|
||||||
|
llvm::MemoryBuffer::getMemBuffer(
|
||||||
|
"#include \"symlink.h\"\n#include \"header.h\"\n"));
|
||||||
|
|
||||||
|
ClangTool Tool(CDB, {"test.cpp", "test2.cpp"},
|
||||||
|
std::make_shared<PCHContainerOperations>(), VFS);
|
||||||
|
Tool.clearArgumentsAdjusters();
|
||||||
|
std::vector<std::string> Deps;
|
||||||
|
TestDependencyScanningAction Action(Deps);
|
||||||
|
Tool.run(&Action);
|
||||||
|
using llvm::sys::path::convert_to_slash;
|
||||||
|
ASSERT_EQ(Deps.size(), 6u);
|
||||||
|
EXPECT_EQ(convert_to_slash(Deps[0]), "/root/test.cpp");
|
||||||
|
EXPECT_EQ(convert_to_slash(Deps[1]), "/root/header.h");
|
||||||
|
EXPECT_EQ(convert_to_slash(Deps[2]), "/root/symlink.h");
|
||||||
|
EXPECT_EQ(convert_to_slash(Deps[3]), "/root/test2.cpp");
|
||||||
|
EXPECT_EQ(convert_to_slash(Deps[4]), "/root/symlink.h");
|
||||||
|
EXPECT_EQ(convert_to_slash(Deps[5]), "/root/header.h");
|
||||||
|
}
|
||||||
|
|
||||||
} // end namespace tooling
|
} // end namespace tooling
|
||||||
} // end namespace clang
|
} // end namespace clang
|
||||||
|
|
Loading…
Reference in New Issue