summaryrefslogtreecommitdiff
path: root/clang/unittests
diff options
context:
space:
mode:
authorBen Langmuir <blangmuir@apple.com>2023-05-04 09:12:52 -0700
committerBen Langmuir <blangmuir@apple.com>2023-05-09 10:05:12 -0700
commitee8ed0b3099e63ba0a18cca42b9cfdf098bc6201 (patch)
tree1623cca40ed615f081bb1a0cfe93a503ccc3d0cb /clang/unittests
parentec77d1f3d9fcf7105b6bda25fb4d0e5ed5afd0c5 (diff)
downloadllvm-ee8ed0b3099e63ba0a18cca42b9cfdf098bc6201.tar.gz
[clang][deps] Teach dep directive scanner about _Pragma
While we cannot handle `_Pragma` used inside macros, we can handle this at the top level, and it some projects use the `_Pragma("once")` spelling like that, which was causing spurious failures in the scanner. Limitations * Cannot handle #define ONCE _Pragma("once"), same issue as using @import in a macro -- ideally we should diagnose this in obvious cases * Our LangOpts are currently fixed, so we are not handling u"" strings or R"()" strings that require C11/C++11. rdar://108629982 Differential Revision: https://reviews.llvm.org/D149884
Diffstat (limited to 'clang/unittests')
-rw-r--r--clang/unittests/Lex/DependencyDirectivesScannerTest.cpp98
1 files changed, 95 insertions, 3 deletions
diff --git a/clang/unittests/Lex/DependencyDirectivesScannerTest.cpp b/clang/unittests/Lex/DependencyDirectivesScannerTest.cpp
index 2f8804784a2e..bc4eee73c1c2 100644
--- a/clang/unittests/Lex/DependencyDirectivesScannerTest.cpp
+++ b/clang/unittests/Lex/DependencyDirectivesScannerTest.cpp
@@ -503,6 +503,92 @@ TEST(MinimizeSourceToDependencyDirectivesTest, Pragma) {
EXPECT_STREQ("#pragma clang module import\n", Out.data());
}
+TEST(MinimizeSourceToDependencyDirectivesTest, UnderscorePragma) {
+ SmallVector<char, 128> Out;
+
+ ASSERT_FALSE(minimizeSourceToDependencyDirectives(R"(_)", Out));
+ EXPECT_STREQ("<TokBeforeEOF>\n", Out.data());
+ ASSERT_FALSE(minimizeSourceToDependencyDirectives(R"(_Pragma)", Out));
+ EXPECT_STREQ("<TokBeforeEOF>\n", Out.data());
+ ASSERT_FALSE(minimizeSourceToDependencyDirectives(R"(_Pragma()", Out));
+ EXPECT_STREQ("<TokBeforeEOF>\n", Out.data());
+ ASSERT_FALSE(minimizeSourceToDependencyDirectives(R"(_Pragma())", Out));
+ EXPECT_STREQ("<TokBeforeEOF>\n", Out.data());
+ ASSERT_FALSE(minimizeSourceToDependencyDirectives(R"(_Pragma(")", Out));
+ EXPECT_STREQ("<TokBeforeEOF>\n", Out.data());
+ ASSERT_FALSE(minimizeSourceToDependencyDirectives(R"(_Pragma("A"))", Out));
+ EXPECT_STREQ("<TokBeforeEOF>\n", Out.data());
+
+ ASSERT_FALSE(minimizeSourceToDependencyDirectives(
+ R"x(_Pragma("push_macro(\"MACRO\")"))x", Out));
+ EXPECT_STREQ(R"x(_Pragma("push_macro(\"MACRO\")"))x"
+ "\n",
+ Out.data());
+
+ ASSERT_FALSE(minimizeSourceToDependencyDirectives(
+ R"x(_Pragma("pop_macro(\"MACRO\")"))x", Out));
+ EXPECT_STREQ(R"x(_Pragma("pop_macro(\"MACRO\")"))x"
+ "\n",
+ Out.data());
+
+ ASSERT_FALSE(minimizeSourceToDependencyDirectives(
+ R"x(_Pragma("include_alias(\"A\", \"B\")"))x", Out));
+ EXPECT_STREQ(R"x(_Pragma("include_alias(\"A\", \"B\")"))x"
+ "\n",
+ Out.data());
+
+ ASSERT_FALSE(minimizeSourceToDependencyDirectives(
+ R"x(_Pragma("include_alias(<A>, <B>)"))x", Out));
+ EXPECT_STREQ(R"x(_Pragma("include_alias(<A>, <B>)"))x"
+ "\n",
+ Out.data());
+
+ ASSERT_FALSE(
+ minimizeSourceToDependencyDirectives(R"(_Pragma("clang"))", Out));
+ EXPECT_STREQ("<TokBeforeEOF>\n", Out.data());
+
+ ASSERT_FALSE(
+ minimizeSourceToDependencyDirectives(R"(_Pragma("clang module"))", Out));
+ EXPECT_STREQ("<TokBeforeEOF>\n", Out.data());
+
+ ASSERT_FALSE(minimizeSourceToDependencyDirectives(
+ R"(_Pragma("clang module impor"))", Out));
+ EXPECT_STREQ("<TokBeforeEOF>\n", Out.data());
+
+ ASSERT_FALSE(minimizeSourceToDependencyDirectives(
+ R"(_Pragma("clang module import"))", Out));
+ EXPECT_STREQ(R"(_Pragma("clang module import"))"
+ "\n",
+ Out.data());
+
+ ASSERT_FALSE(minimizeSourceToDependencyDirectives(
+ R"(_Pragma("clang \
+ module \
+ import"))",
+ Out));
+ EXPECT_STREQ(R"(_Pragma("clang \
+ module \
+ import"))"
+ "\n",
+ Out.data());
+
+ ASSERT_FALSE(minimizeSourceToDependencyDirectives(
+ R"(_Pragma(L"clang module import"))", Out));
+ EXPECT_STREQ(R"(_Pragma(L"clang module import"))"
+ "\n",
+ Out.data());
+
+ // FIXME: u"" strings depend on using C11 language mode
+ ASSERT_FALSE(minimizeSourceToDependencyDirectives(
+ R"(_Pragma(u"clang module import"))", Out));
+ EXPECT_STREQ("<TokBeforeEOF>\n", Out.data());
+
+ // FIXME: R"()" strings depend on using C++ 11 language mode
+ ASSERT_FALSE(minimizeSourceToDependencyDirectives(
+ R"(_Pragma(R"abc(clang module import)abc"))", Out));
+ EXPECT_STREQ("<TokBeforeEOF>\n", Out.data());
+}
+
TEST(MinimizeSourceToDependencyDirectivesTest, Include) {
SmallVector<char, 128> Out;
@@ -757,20 +843,26 @@ TEST(MinimizeSourceToDependencyDirectivesTest, PragmaOnce) {
#pragma once
// another comment
#include <test.h>
+_Pragma("once")
)";
ASSERT_FALSE(
minimizeSourceToDependencyDirectives(Source, Out, Tokens, Directives));
- EXPECT_STREQ("#pragma once\n#include <test.h>\n", Out.data());
- ASSERT_EQ(Directives.size(), 3u);
+ EXPECT_STREQ("#pragma once\n#include <test.h>\n_Pragma(\"once\")\n",
+ Out.data());
+ ASSERT_EQ(Directives.size(), 4u);
EXPECT_EQ(Directives[0].Kind, dependency_directives_scan::pp_pragma_once);
+ EXPECT_EQ(Directives[2].Kind, dependency_directives_scan::pp_pragma_once);
Source = R"(// comment
#pragma once extra tokens
// another comment
#include <test.h>
+ _Pragma("once") extra tokens
)";
ASSERT_FALSE(minimizeSourceToDependencyDirectives(Source, Out));
- EXPECT_STREQ("#pragma once extra tokens\n#include <test.h>\n", Out.data());
+ EXPECT_STREQ("#pragma once extra tokens\n#include "
+ "<test.h>\n_Pragma(\"once\")<TokBeforeEOF>\n",
+ Out.data());
}
TEST(MinimizeSourceToDependencyDirectivesTest,