mirror of
https://github.com/capstone-engine/llvm-capstone.git
synced 2025-02-12 12:48:59 +00:00
[clang-scan-deps] do not skip empty #if/#elif in the minimizer to avoid missing __has_include
dependencies
This patch makes the minimizer more conservative to avoid missing dependency files that are brought in by __has_include PP expressions that occur in a condition of an #if/#elif that was previously skipped. The __has_include PP expressions can be used in an #if/#elif either directly, or through macro expansion, so we can't detect them at the time of minimization. Differential Revision: https://reviews.llvm.org/D70936
This commit is contained in:
parent
cf81714a7e
commit
389530524b
@ -763,12 +763,13 @@ bool Minimizer::lexEndif(const char *&First, const char *const End) {
|
||||
if (top() == pp_else)
|
||||
popToken();
|
||||
|
||||
// Strip out "#elif" if they're empty.
|
||||
while (top() == pp_elif)
|
||||
popToken();
|
||||
|
||||
// If "#if" is empty, strip it and skip the "#endif".
|
||||
if (top() == pp_if || top() == pp_ifdef || top() == pp_ifndef) {
|
||||
// If "#ifdef" is empty, strip it and skip the "#endif".
|
||||
//
|
||||
// FIXME: Once/if Clang starts disallowing __has_include in macro expansions,
|
||||
// we can skip empty `#if` and `#elif` blocks as well after scanning for a
|
||||
// literal __has_include in the condition. Even without that rule we could
|
||||
// drop the tokens if we scan for identifiers in the condition and find none.
|
||||
if (top() == pp_ifdef || top() == pp_ifndef) {
|
||||
popToken();
|
||||
skipLine(First, End);
|
||||
return false;
|
||||
|
7
clang/test/ClangScanDeps/Inputs/has_include_if_elif.json
Normal file
7
clang/test/ClangScanDeps/Inputs/has_include_if_elif.json
Normal file
@ -0,0 +1,7 @@
|
||||
[
|
||||
{
|
||||
"directory": "DIR",
|
||||
"command": "clang -E DIR/has_include_if_elif2.cpp -IInputs",
|
||||
"file": "DIR/has_include_if_elif2.cpp"
|
||||
}
|
||||
]
|
38
clang/test/ClangScanDeps/has_include_if_elif.cpp
Normal file
38
clang/test/ClangScanDeps/has_include_if_elif.cpp
Normal file
@ -0,0 +1,38 @@
|
||||
// RUN: rm -rf %t.dir
|
||||
// RUN: rm -rf %t.cdb
|
||||
// RUN: mkdir -p %t.dir
|
||||
// RUN: cp %s %t.dir/has_include_if_elif2.cpp
|
||||
// RUN: mkdir %t.dir/Inputs
|
||||
// RUN: cp %S/Inputs/header.h %t.dir/Inputs/header.h
|
||||
// RUN: cp %S/Inputs/header.h %t.dir/Inputs/header2.h
|
||||
// RUN: cp %S/Inputs/header.h %t.dir/Inputs/header3.h
|
||||
// RUN: cp %S/Inputs/header.h %t.dir/Inputs/header4.h
|
||||
// RUN: sed -e "s|DIR|%/t.dir|g" %S/Inputs/has_include_if_elif.json > %t.cdb
|
||||
//
|
||||
// RUN: clang-scan-deps -compilation-database %t.cdb -j 1 -mode preprocess-minimized-sources | \
|
||||
// RUN: FileCheck %s
|
||||
// RUN: clang-scan-deps -compilation-database %t.cdb -j 1 -mode preprocess | \
|
||||
// RUN: FileCheck %s
|
||||
|
||||
#if __has_include("header.h")
|
||||
#endif
|
||||
|
||||
#if 0
|
||||
#elif __has_include("header2.h")
|
||||
#endif
|
||||
|
||||
#define H3 __has_include("header3.h")
|
||||
#if H3
|
||||
#endif
|
||||
|
||||
#define H4 __has_include("header4.h")
|
||||
|
||||
#if 0
|
||||
#elif H4
|
||||
#endif
|
||||
|
||||
// CHECK: has_include_if_elif2.cpp
|
||||
// CHECK-NEXT: Inputs{{/|\\}}header.h
|
||||
// CHECK-NEXT: Inputs{{/|\\}}header2.h
|
||||
// CHECK-NEXT: Inputs{{/|\\}}header3.h
|
||||
// CHECK-NEXT: Inputs{{/|\\}}header4.h
|
@ -328,12 +328,17 @@ TEST(MinimizeSourceToDependencyDirectivesTest, EmptyIfdef) {
|
||||
SmallVector<char, 128> Out;
|
||||
|
||||
ASSERT_FALSE(minimizeSourceToDependencyDirectives("#ifdef A\n"
|
||||
"void skip();\n"
|
||||
"#elif B\n"
|
||||
"#elif C\n"
|
||||
"#else D\n"
|
||||
"#endif\n",
|
||||
Out));
|
||||
EXPECT_STREQ("", Out.data());
|
||||
EXPECT_STREQ("#ifdef A\n"
|
||||
"#elif B\n"
|
||||
"#elif C\n"
|
||||
"#endif\n",
|
||||
Out.data());
|
||||
}
|
||||
|
||||
TEST(MinimizeSourceToDependencyDirectivesTest, Pragma) {
|
||||
@ -507,6 +512,12 @@ TEST(MinimizeSourceToDependencyDirectivesTest, PoundWarningAndError) {
|
||||
for (auto Source : {
|
||||
"#warning \\\n#include <t.h>\n",
|
||||
"#error \\\n#include <t.h>\n",
|
||||
}) {
|
||||
ASSERT_FALSE(minimizeSourceToDependencyDirectives(Source, Out));
|
||||
EXPECT_STREQ("", Out.data());
|
||||
}
|
||||
|
||||
for (auto Source : {
|
||||
"#if MACRO\n#warning '\n#endif\n",
|
||||
"#if MACRO\n#warning \"\n#endif\n",
|
||||
"#if MACRO\n#warning /*\n#endif\n",
|
||||
@ -515,7 +526,7 @@ TEST(MinimizeSourceToDependencyDirectivesTest, PoundWarningAndError) {
|
||||
"#if MACRO\n#error /*\n#endif\n",
|
||||
}) {
|
||||
ASSERT_FALSE(minimizeSourceToDependencyDirectives(Source, Out));
|
||||
EXPECT_STREQ("", Out.data());
|
||||
EXPECT_STREQ("#if MACRO\n#endif\n", Out.data());
|
||||
}
|
||||
}
|
||||
|
||||
@ -543,7 +554,7 @@ TEST(MinimizeSourceToDependencyDirectivesTest, CharacterLiteralPrefixL) {
|
||||
#include <test.h>
|
||||
)";
|
||||
ASSERT_FALSE(minimizeSourceToDependencyDirectives(Source, Out));
|
||||
EXPECT_STREQ("#include <test.h>\n", Out.data());
|
||||
EXPECT_STREQ("#if DEBUG\n#endif\n#include <test.h>\n", Out.data());
|
||||
}
|
||||
|
||||
TEST(MinimizeSourceToDependencyDirectivesTest, CharacterLiteralPrefixU) {
|
||||
|
Loading…
x
Reference in New Issue
Block a user