Skip to content

Commit

Permalink
Track skipped files in dependency scanning.
Browse files Browse the repository at this point in the history
It's possible for a header to be a symlink to another header. In this
case both will be represented by clang::FileEntry with the same UID and
they'll use the same clang::HeaderFileInfo.

If you include both headers and use some single-inclusion mechanism
like a header guard or #import, one header will get a FileChanged
callback, and another FileSkipped.

So that we get an accurate dependency file, we therefore need to also
implement the FileSkipped callback in dependency scanning.

Patch by Pete Cooper.

Reviewers: bruno, pete

Reviewed By: bruno

Subscribers: cfe-commits, jkorous, vsapsai

Differential Revision: https://reviews.llvm.org/D30881

llvm-svn: 331319
  • Loading branch information
vsapsai committed May 1, 2018
1 parent ddbd2b5 commit 210f0e8
Show file tree
Hide file tree
Showing 3 changed files with 41 additions and 0 deletions.
14 changes: 14 additions & 0 deletions clang/lib/Frontend/DependencyFile.cpp
Expand Up @@ -185,6 +185,10 @@ class DFGImpl : public PPCallbacks {
void FileChanged(SourceLocation Loc, FileChangeReason Reason,
SrcMgr::CharacteristicKind FileType,
FileID PrevFID) override;

void FileSkipped(const FileEntry &SkippedFile, const Token &FilenameTok,
SrcMgr::CharacteristicKind FileType) override;

void InclusionDirective(SourceLocation HashLoc, const Token &IncludeTok,
StringRef FileName, bool IsAngled,
CharSourceRange FilenameRange, const FileEntry *File,
Expand Down Expand Up @@ -291,6 +295,16 @@ void DFGImpl::FileChanged(SourceLocation Loc,
AddFilename(llvm::sys::path::remove_leading_dotslash(Filename));
}

void DFGImpl::FileSkipped(const FileEntry &SkippedFile,
const Token &FilenameTok,
SrcMgr::CharacteristicKind FileType) {
StringRef Filename = SkippedFile.getName();
if (!FileMatchesDepCriteria(Filename.data(), FileType))
return;

AddFilename(llvm::sys::path::remove_leading_dotslash(Filename));
}

void DFGImpl::InclusionDirective(SourceLocation HashLoc,
const Token &IncludeTok,
StringRef FileName,
Expand Down
@@ -0,0 +1,3 @@
#ifndef HEADER_GUARD
#define HEADER_GUARD
#endif
24 changes: 24 additions & 0 deletions clang/test/Frontend/dependency-gen-symlink.c
@@ -0,0 +1,24 @@
// REQUIRES: shell

// Basic test
// RUN: rm -rf %t.dir
// RUN: mkdir %t.dir
// RUN: mkdir %t.dir/a
// RUN: mkdir %t.dir/b
// RUN: echo "#ifndef HEADER_A" > %t.dir/a/header.h
// RUN: echo "#define HEADER_A" >> %t.dir/a/header.h
// RUN: echo "#endif" >> %t.dir/a/header.h
// RUN: ln -s %t.dir/a/header.h %t.dir/b/header.h

// RUN: %clang_cc1 -dependency-file %t.dir/file.deps -MT %s.o %s -fsyntax-only -I %t.dir -isystem %S/Inputs/SystemHeaderPrefix
// RUN: FileCheck -input-file=%t.dir/file.deps %s
// CHECK: dependency-gen-symlink.c.o
// CHECK: dependency-gen-symlink.c
// CHECK: a/header.h
// CHECK: b/header.h
// CHECK-NOT: with-header-guard.h
#include "a/header.h"
#include "b/header.h"
// System header shouldn't be included in dependencies.
#include <with-header-guard.h>
#include <with-header-guard.h>

0 comments on commit 210f0e8

Please sign in to comment.