Skip to content

Commit 81ad91c

Browse files
[IncludeTree] Fix PPCallback for include tree that can cause missing .d file
For IncludeDirective callback from include-tree, do not callback with null FileEntry as that dependency collector using that to indicate a missing header include, and will not emit dependency file in this case. Unlike a regular callback from Lexer, include tree doesn't resolve headers so it cannot callback with a FileEntry to the header file being included when the include is actually a module. The behavior for the callback has to be changed slightly that it uses the ASTFile FileEntry. rdar://126885995
1 parent 8000b5d commit 81ad91c

File tree

2 files changed

+74
-6
lines changed

2 files changed

+74
-6
lines changed

clang/lib/Lex/PPDirectives.cpp

Lines changed: 12 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -2010,11 +2010,10 @@ void Preprocessor::HandleIncludeDirective(SourceLocation HashLoc,
20102010
SrcMgr::CharacteristicKind FileCharacter =
20112011
SourceMgr.getFileCharacteristic(FilenameTok.getLocation());
20122012
if (SuggestedModule)
2013-
Callbacks->InclusionDirective(HashLoc, IncludeTok, Filename, isAngled,
2014-
FilenameRange, OptionalFileEntryRef(),
2015-
/*SearchPath=*/"", /*RelativePath=*/"",
2016-
SuggestedModule,
2017-
/*ModuleImported=*/true, FileCharacter);
2013+
Callbacks->InclusionDirective(
2014+
HashLoc, IncludeTok, Filename, isAngled, FilenameRange, FileRef,
2015+
/*SearchPath=*/"", /*RelativePath=*/"", SuggestedModule,
2016+
/*ModuleImported=*/true, FileCharacter);
20182017
else
20192018
Callbacks->InclusionDirective(
20202019
HashLoc, IncludeTok, Filename, isAngled, FilenameRange, FileRef,
@@ -2096,7 +2095,14 @@ void Preprocessor::HandleIncludeDirective(SourceLocation HashLoc,
20962095
return;
20972096
}
20982097

2099-
InclusionCallback({}, Imported);
2098+
// PPCallback for IncludeDirective. Using the AST file as the FileEntry in
2099+
// the callback to indicate this is not a missing header. Note this is not
2100+
// the same behavior as non-include-tree build where the FileEntry is for
2101+
// the header file.
2102+
// FIXME: Need to clarify what `File` means in the callback, and if that
2103+
// can be the module file entry instead of header file entry.
2104+
Module *M = Imported;
2105+
InclusionCallback(M->getASTFile(), Imported);
21002106
makeModuleVisible(Imported, EndLoc);
21012107
if (IncludeTok.getIdentifierInfo()->getPPKeywordID() !=
21022108
tok::pp___include_macros)
Lines changed: 62 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,62 @@
1+
// REQUIRES: ondisk_cas
2+
3+
// RUN: rm -rf %t
4+
// RUN: split-file %s %t
5+
// RUN: sed "s|DIR|%/t|g" %t/cdb.json.template > %t/cdb.json
6+
7+
// RUN: clang-scan-deps -compilation-database %t/cdb.json \
8+
// RUN: -cas-path %t/cas -format experimental-include-tree-full > %t/deps.json
9+
10+
// RUN: %deps-to-rsp %t/deps.json --module-name Mod_Private > %t/private.rsp
11+
// RUN: %deps-to-rsp %t/deps.json --module-name Mod > %t/mod.rsp
12+
// RUN: %deps-to-rsp %t/deps.json --tu-index 0 > %t/tu.rsp
13+
// RUN: %clang @%t/private.rsp
14+
// RUN: %clang @%t/mod.rsp
15+
// RUN: %clang @%t/tu.rsp -dependency-dot %t/tu.dot
16+
/// Check dependency file is generated.
17+
// RUN: find %t/module-cache -name "*.d" | wc -l | grep 2
18+
// RUN: FileCheck %s -input-file=%t/tu.d
19+
20+
// CHECK: dependencies:
21+
// CHECK-DAG: tu.m
22+
// CHECK-DAG: A.h
23+
24+
// RUN: FileCheck %s -input-file=%t/tu.dot -check-prefix DOT
25+
// DOT: digraph "dependencies"
26+
// DOT-DAG: [[TU:header_[0-9]+]] [ shape="box", label="{{.*}}{{/|\\}}tu.m"];
27+
// DOT-DAG: [[HEADER:header_[0-9]+]] [ shape="box", label="{{.*}}{{/|\\}}A.h"];
28+
// DOT-DAG: [[PCM:header_[0-9]+]] [ shape="box", label="{{.*}}{{/|\\}}Mod-{{.*}}.pcm"];
29+
// DOT-DAG: [[TU]] -> [[HEADER]]
30+
// DOT-DAG: [[HEADER]] -> [[PCM]]
31+
32+
//--- cdb.json.template
33+
[{
34+
"file": "DIR/tu.m",
35+
"directory": "DIR",
36+
"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"
37+
}]
38+
39+
//--- Mod.framework/Modules/module.modulemap
40+
framework module Mod { header "Mod.h" }
41+
42+
//--- Mod.framework/Modules/module.private.modulemap
43+
framework module Mod_Private { header "Priv.h" }
44+
45+
//--- module.modulemap
46+
module A {
47+
header "A.h"
48+
export *
49+
}
50+
51+
//--- A.h
52+
#include <Mod/Mod.h>
53+
54+
//--- Mod.framework/Headers/Mod.h
55+
#include <Mod/Priv.h>
56+
void pub(void);
57+
58+
//--- Mod.framework/PrivateHeaders/Priv.h
59+
void priv(void);
60+
61+
//--- tu.m
62+
#import "A.h"

0 commit comments

Comments
 (0)