diff --git a/clang/lib/Lex/PPDirectives.cpp b/clang/lib/Lex/PPDirectives.cpp index cb964bd5e451f..536e5bd454779 100644 --- a/clang/lib/Lex/PPDirectives.cpp +++ b/clang/lib/Lex/PPDirectives.cpp @@ -2010,11 +2010,10 @@ void Preprocessor::HandleIncludeDirective(SourceLocation HashLoc, SrcMgr::CharacteristicKind FileCharacter = SourceMgr.getFileCharacteristic(FilenameTok.getLocation()); if (SuggestedModule) - Callbacks->InclusionDirective(HashLoc, IncludeTok, Filename, isAngled, - FilenameRange, OptionalFileEntryRef(), - /*SearchPath=*/"", /*RelativePath=*/"", - SuggestedModule, - /*ModuleImported=*/true, FileCharacter); + Callbacks->InclusionDirective( + HashLoc, IncludeTok, Filename, isAngled, FilenameRange, FileRef, + /*SearchPath=*/"", /*RelativePath=*/"", SuggestedModule, + /*ModuleImported=*/true, FileCharacter); else Callbacks->InclusionDirective( HashLoc, IncludeTok, Filename, isAngled, FilenameRange, FileRef, @@ -2096,7 +2095,14 @@ void Preprocessor::HandleIncludeDirective(SourceLocation HashLoc, return; } - InclusionCallback({}, Imported); + // PPCallback for IncludeDirective. Using the AST file as the FileEntry in + // the callback to indicate this is not a missing header. Note this is not + // the same behavior as non-include-tree build where the FileEntry is for + // the header file. + // FIXME: Need to clarify what `File` means in the callback, and if that + // can be the module file entry instead of header file entry. + Module *M = Imported; + InclusionCallback(M->getASTFile(), Imported); makeModuleVisible(Imported, EndLoc); if (IncludeTok.getIdentifierInfo()->getPPKeywordID() != tok::pp___include_macros) diff --git a/clang/test/ClangScanDeps/modules-include-tree-dependency-file.c b/clang/test/ClangScanDeps/modules-include-tree-dependency-file.c new file mode 100644 index 0000000000000..fa5c123975401 --- /dev/null +++ b/clang/test/ClangScanDeps/modules-include-tree-dependency-file.c @@ -0,0 +1,62 @@ +// REQUIRES: ondisk_cas + +// RUN: rm -rf %t +// RUN: split-file %s %t +// RUN: sed "s|DIR|%/t|g" %t/cdb.json.template > %t/cdb.json + +// RUN: clang-scan-deps -compilation-database %t/cdb.json \ +// RUN: -cas-path %t/cas -format experimental-include-tree-full > %t/deps.json + +// RUN: %deps-to-rsp %t/deps.json --module-name Mod_Private > %t/private.rsp +// RUN: %deps-to-rsp %t/deps.json --module-name Mod > %t/mod.rsp +// RUN: %deps-to-rsp %t/deps.json --tu-index 0 > %t/tu.rsp +// RUN: %clang @%t/private.rsp +// RUN: %clang @%t/mod.rsp +// RUN: %clang @%t/tu.rsp -dependency-dot %t/tu.dot +/// Check dependency file is generated. +// RUN: find %t/module-cache -name "*.d" | wc -l | grep 2 +// RUN: FileCheck %s -input-file=%t/tu.d + +// CHECK: dependencies: +// CHECK-DAG: tu.m +// CHECK-DAG: A.h + +// RUN: FileCheck %s -input-file=%t/tu.dot -check-prefix DOT +// DOT: digraph "dependencies" +// DOT-DAG: [[TU:header_[0-9]+]] [ shape="box", label="{{.*}}{{/|\\}}tu.m"]; +// DOT-DAG: [[HEADER:header_[0-9]+]] [ shape="box", label="{{.*}}{{/|\\}}A.h"]; +// DOT-DAG: [[PCM:header_[0-9]+]] [ shape="box", label="{{.*}}{{/|\\}}Mod-{{.*}}.pcm"]; +// DOT-DAG: [[TU]] -> [[HEADER]] +// DOT-DAG: [[HEADER]] -> [[PCM]] + +//--- cdb.json.template +[{ + "file": "DIR/tu.m", + "directory": "DIR", + "command": "clang -fsyntax-only DIR/tu.m -F DIR -I DIR -fmodule-name=A -fmodules -fimplicit-modules -fimplicit-module-maps -fmodules-cache-path=DIR/module-cache -MMD -MT dependencies -MF DIR/tu.d" +}] + +//--- Mod.framework/Modules/module.modulemap +framework module Mod { header "Mod.h" } + +//--- Mod.framework/Modules/module.private.modulemap +framework module Mod_Private { header "Priv.h" } + +//--- module.modulemap +module A { + header "A.h" + export * +} + +//--- A.h +#include + +//--- Mod.framework/Headers/Mod.h +#include +void pub(void); + +//--- Mod.framework/PrivateHeaders/Priv.h +void priv(void); + +//--- tu.m +#import "A.h"