Skip to content

Commit 6f5414e

Browse files
committed
[clang][cas] Add test for #pragma clang system_header
This verifies include-tree matches uncached build diagnostics when using `#pragma clang system_header`, which applies to transitive includes. rdar://108627403 (cherry picked from commit 0bfdf3b)
1 parent d67ff0e commit 6f5414e

File tree

2 files changed

+76
-2
lines changed

2 files changed

+76
-2
lines changed
Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
// RUN: rm -rf %t
2+
// RUN: split-file %s %t
3+
// RUN: sed -e "s|DIR|%/t|g" %t/cdb.json.template > %t/cdb.json
4+
5+
// RUN: clang-scan-deps -cas-path %t/cas -format experimental-include-tree-full \
6+
// RUN: -compilation-database %t/cdb.json > %t/deps.json
7+
// RUN: %deps-to-rsp %t/deps.json --tu-index 0 > %t/tu.rsp
8+
9+
// Confirm we match the non-include-tree build:
10+
// RUN: %clang -fsyntax-only -Wextra-semi %t/tu.c 2>&1 | FileCheck %s
11+
// RUN: %clang @%t/tu.rsp 2>&1 | FileCheck %s
12+
13+
// CHECK: sys.h:1:7: warning: extra ';'
14+
// CHECK-NOT: warning: extra ';'
15+
// CHECK: tu.c:{{.*}}: warning: extra ';'
16+
17+
//--- cdb.json.template
18+
[{
19+
"directory": "DIR",
20+
"command": "clang -fsyntax-only -Wextra-semi DIR/tu.c",
21+
"file": "DIR/tu.c"
22+
}]
23+
24+
//--- sys.h
25+
int x;;
26+
#pragma clang system_header
27+
int y;;
28+
#include "other.h"
29+
30+
//--- other.h
31+
int z;;
32+
33+
//--- tu.c
34+
#include "sys.h"
35+
int w;;
36+
37+
int main() {
38+
return x + y + z;
39+
}

clang/unittests/CAS/IncludeTreeTest.cpp

Lines changed: 37 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@ TEST(IncludeTree, IncludeTreeScan) {
2323
StringRef MainContents = R"(
2424
#include "a1.h"
2525
#include "sys.h"
26+
#include "sys_directive.h"
2627
)";
2728
StringRef A1Contents = R"(
2829
#if __has_include("other.h")
@@ -32,10 +33,16 @@ TEST(IncludeTree, IncludeTreeScan) {
3233
#include "b1.h"
3334
#endif
3435
)";
36+
StringRef SysDirectiveContents = R"(
37+
#pragma clang system_header
38+
#include "sys_indirect.h"
39+
)";
3540
add("t.cpp", MainContents);
3641
add("a1.h", A1Contents);
3742
add("b1.h", "");
3843
add("sys/sys.h", "");
44+
add("sys_directive.h", SysDirectiveContents);
45+
add("sys_indirect.h", "");
3946
std::unique_ptr<llvm::vfs::FileSystem> VFS =
4047
llvm::cas::createCASProvidingFileSystem(DB, FS);
4148

@@ -63,6 +70,8 @@ TEST(IncludeTree, IncludeTreeScan) {
6370
Optional<IncludeTree::File> A1File;
6471
Optional<IncludeTree::File> B1File;
6572
Optional<IncludeTree::File> SysFile;
73+
Optional<IncludeTree::File> SysDirectiveFile;
74+
Optional<IncludeTree::File> SysIndirectFile;
6675

6776
Optional<IncludeTree> Main;
6877
ASSERT_THAT_ERROR(Root->getMainFileTree().moveInto(Main), llvm::Succeeded());
@@ -75,7 +84,7 @@ TEST(IncludeTree, IncludeTreeScan) {
7584
EXPECT_EQ(FI.Filename, "t.cpp");
7685
EXPECT_EQ(FI.Contents, MainContents);
7786
}
78-
ASSERT_EQ(Main->getNumIncludes(), uint32_t(3));
87+
ASSERT_EQ(Main->getNumIncludes(), uint32_t(4));
7988

8089
Optional<IncludeTree> Predef;
8190
ASSERT_THAT_ERROR(Main->getIncludeTree(0).moveInto(Predef),
@@ -132,6 +141,28 @@ TEST(IncludeTree, IncludeTreeScan) {
132141
ASSERT_EQ(Sys->getNumIncludes(), uint32_t(0));
133142
}
134143

144+
Optional<IncludeTree> SysDirective;
145+
ASSERT_THAT_ERROR(Main->getIncludeTree(3).moveInto(SysDirective),
146+
llvm::Succeeded());
147+
EXPECT_EQ(Main->getIncludeOffset(3), uint32_t(73));
148+
{
149+
ASSERT_THAT_ERROR(SysDirective->getBaseFile().moveInto(SysDirectiveFile),
150+
llvm::Succeeded());
151+
// Note: system_header directive injects a line directive, so C_User is for
152+
// the start of the file here.
153+
EXPECT_EQ(SysDirective->getFileCharacteristic(), SrcMgr::C_User);
154+
ASSERT_EQ(SysDirective->getNumIncludes(), uint32_t(1));
155+
Optional<IncludeTree> SysIndirect;
156+
ASSERT_THAT_ERROR(SysDirective->getIncludeTree(0).moveInto(SysIndirect),
157+
llvm::Succeeded());
158+
{
159+
ASSERT_THAT_ERROR(SysIndirect->getBaseFile().moveInto(SysIndirectFile),
160+
llvm::Succeeded());
161+
EXPECT_EQ(SysIndirect->getFileCharacteristic(), SrcMgr::C_System);
162+
ASSERT_EQ(SysIndirect->getNumIncludes(), uint32_t(0));
163+
}
164+
}
165+
135166
Optional<IncludeTree::FileList> FileList;
136167
ASSERT_THAT_ERROR(Root->getFileList().moveInto(FileList), llvm::Succeeded());
137168

@@ -143,7 +174,7 @@ TEST(IncludeTree, IncludeTreeScan) {
143174
}),
144175
llvm::Succeeded());
145176

146-
ASSERT_EQ(Files.size(), size_t(4));
177+
ASSERT_EQ(Files.size(), size_t(6));
147178
EXPECT_EQ(Files[0].first.getRef(), MainFile->getRef());
148179
EXPECT_EQ(Files[0].second, MainContents.size());
149180
EXPECT_EQ(Files[1].first.getRef(), A1File->getRef());
@@ -152,6 +183,10 @@ TEST(IncludeTree, IncludeTreeScan) {
152183
EXPECT_EQ(Files[2].second, IncludeTree::FileList::FileSizeTy(0));
153184
EXPECT_EQ(Files[3].first.getRef(), SysFile->getRef());
154185
EXPECT_EQ(Files[3].second, IncludeTree::FileList::FileSizeTy(0));
186+
EXPECT_EQ(Files[4].first.getRef(), SysDirectiveFile->getRef());
187+
EXPECT_EQ(Files[4].second, SysDirectiveContents.size());
188+
EXPECT_EQ(Files[5].first.getRef(), SysIndirectFile->getRef());
189+
EXPECT_EQ(Files[5].second, IncludeTree::FileList::FileSizeTy(0));
155190
}
156191

157192
TEST(IncludeTree, IncludeTreeFileList) {

0 commit comments

Comments
 (0)