r368381 - [clang-scan-deps] Add minimizer support for C++20 modules.
Michael J. Spencer via cfe-commits
cfe-commits at lists.llvm.org
Thu Aug 8 19:01:11 PDT 2019
Author: mspencer
Date: Thu Aug 8 19:01:10 2019
New Revision: 368381
URL: http://llvm.org/viewvc/llvm-project?rev=368381&view=rev
Log:
[clang-scan-deps] Add minimizer support for C++20 modules.
This only adds support to the minimizer, it doesn't actually capture the dependencies yet.
Modified:
cfe/trunk/include/clang/Lex/DependencyDirectivesSourceMinimizer.h
cfe/trunk/lib/Lex/DependencyDirectivesSourceMinimizer.cpp
cfe/trunk/unittests/Lex/DependencyDirectivesSourceMinimizerTest.cpp
Modified: cfe/trunk/include/clang/Lex/DependencyDirectivesSourceMinimizer.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Lex/DependencyDirectivesSourceMinimizer.h?rev=368381&r1=368380&r2=368381&view=diff
==============================================================================
--- cfe/trunk/include/clang/Lex/DependencyDirectivesSourceMinimizer.h (original)
+++ cfe/trunk/include/clang/Lex/DependencyDirectivesSourceMinimizer.h Thu Aug 8 19:01:10 2019
@@ -47,6 +47,9 @@ enum TokenKind {
pp_else,
pp_endif,
decl_at_import,
+ cxx_export_decl,
+ cxx_module_decl,
+ cxx_import_decl,
pp_eof,
};
Modified: cfe/trunk/lib/Lex/DependencyDirectivesSourceMinimizer.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Lex/DependencyDirectivesSourceMinimizer.cpp?rev=368381&r1=368380&r2=368381&view=diff
==============================================================================
--- cfe/trunk/lib/Lex/DependencyDirectivesSourceMinimizer.cpp (original)
+++ cfe/trunk/lib/Lex/DependencyDirectivesSourceMinimizer.cpp Thu Aug 8 19:01:10 2019
@@ -59,6 +59,7 @@ private:
LLVM_NODISCARD bool minimizeImpl(const char *First, const char *const End);
LLVM_NODISCARD bool lexPPLine(const char *&First, const char *const End);
LLVM_NODISCARD bool lexAt(const char *&First, const char *const End);
+ LLVM_NODISCARD bool lexModule(const char *&First, const char *const End);
LLVM_NODISCARD bool lexDefine(const char *&First, const char *const End);
LLVM_NODISCARD bool lexPragma(const char *&First, const char *const End);
LLVM_NODISCARD bool lexEndif(const char *&First, const char *const End);
@@ -576,6 +577,59 @@ bool Minimizer::lexAt(const char *&First
return false;
}
+bool Minimizer::lexModule(const char *&First, const char *const End) {
+ IdInfo Id = lexIdentifier(First, End);
+ First = Id.Last;
+ bool Export = false;
+ if (Id.Name == "export") {
+ Export = true;
+ skipWhitespace(First, End);
+ if (!isIdentifierBody(*First)) {
+ skipLine(First, End);
+ return false;
+ }
+ Id = lexIdentifier(First, End);
+ First = Id.Last;
+ }
+
+ if (Id.Name != "module" && Id.Name != "import") {
+ skipLine(First, End);
+ return false;
+ }
+
+ skipWhitespace(First, End);
+
+ // Ignore this as a module directive if the next character can't be part of
+ // an import.
+
+ switch (*First) {
+ case ':':
+ case '<':
+ case '"':
+ break;
+ default:
+ if (!isIdentifierBody(*First)) {
+ skipLine(First, End);
+ return false;
+ }
+ }
+
+ if (Export) {
+ makeToken(cxx_export_decl);
+ append("export ");
+ }
+
+ if (Id.Name == "module")
+ makeToken(cxx_module_decl);
+ else
+ makeToken(cxx_import_decl);
+ append(Id.Name);
+ append(" ");
+ printToNewline(First, End);
+ append("\n");
+ return false;
+}
+
bool Minimizer::lexDefine(const char *&First, const char *const End) {
makeToken(pp_define);
append("#define ");
@@ -677,6 +731,18 @@ bool Minimizer::lexDefault(TokenKind Kin
return false;
}
+static bool isStartOfRelevantLine(char First) {
+ switch (First) {
+ case '#':
+ case '@':
+ case 'i':
+ case 'e':
+ case 'm':
+ return true;
+ }
+ return false;
+}
+
bool Minimizer::lexPPLine(const char *&First, const char *const End) {
assert(First != End);
@@ -685,7 +751,7 @@ bool Minimizer::lexPPLine(const char *&F
if (First == End)
return false;
- if (*First != '#' && *First != '@') {
+ if (!isStartOfRelevantLine(*First)) {
skipLine(First, End);
assert(First <= End);
return false;
@@ -695,6 +761,9 @@ bool Minimizer::lexPPLine(const char *&F
if (*First == '@')
return lexAt(First, End);
+ if (*First == 'i' || *First == 'e' || *First == 'm')
+ return lexModule(First, End);
+
// Handle preprocessing directives.
++First; // Skip over '#'.
skipWhitespace(First, End);
Modified: cfe/trunk/unittests/Lex/DependencyDirectivesSourceMinimizerTest.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/unittests/Lex/DependencyDirectivesSourceMinimizerTest.cpp?rev=368381&r1=368380&r2=368381&view=diff
==============================================================================
--- cfe/trunk/unittests/Lex/DependencyDirectivesSourceMinimizerTest.cpp (original)
+++ cfe/trunk/unittests/Lex/DependencyDirectivesSourceMinimizerTest.cpp Thu Aug 8 19:01:10 2019
@@ -60,7 +60,9 @@ TEST(MinimizeSourceToDependencyDirective
"#__include_macros <A>\n"
"#import <A>\n"
"@import A;\n"
- "#pragma clang module import A\n",
+ "#pragma clang module import A\n"
+ "export module m;\n"
+ "import m;\n",
Out, Tokens));
EXPECT_EQ(pp_define, Tokens[0].K);
EXPECT_EQ(pp_undef, Tokens[1].K);
@@ -76,7 +78,10 @@ TEST(MinimizeSourceToDependencyDirective
EXPECT_EQ(pp_import, Tokens[11].K);
EXPECT_EQ(decl_at_import, Tokens[12].K);
EXPECT_EQ(pp_pragma_import, Tokens[13].K);
- EXPECT_EQ(pp_eof, Tokens[14].K);
+ EXPECT_EQ(cxx_export_decl, Tokens[14].K);
+ EXPECT_EQ(cxx_module_decl, Tokens[15].K);
+ EXPECT_EQ(cxx_import_decl, Tokens[16].K);
+ EXPECT_EQ(pp_eof, Tokens[17].K);
}
TEST(MinimizeSourceToDependencyDirectivesTest, Define) {
@@ -568,4 +573,48 @@ TEST(MinimizeSourceToDependencyDirective
EXPECT_STREQ("#pragma once\n#include <test.h>\n", Out.data());
}
+TEST(MinimizeSourceToDependencyDirectivesTest, CxxModules) {
+ SmallVector<char, 128> Out;
+ SmallVector<Token, 4> Tokens;
+
+ StringRef Source = R"(
+ module;
+ #include "textual-header.h"
+
+ export module m;
+ exp\
+ort \
+ import \
+ :l [[rename]];
+
+ export void f();
+
+ void h() {
+ import.a = 3;
+ import = 3;
+ import <<= 3;
+ import->a = 3;
+ import();
+ import . a();
+
+ import a b d e d e f e;
+ import foo [[no_unique_address]];
+ import foo();
+ import f(:sefse);
+ import f(->a = 3);
+ }
+ )";
+ ASSERT_FALSE(minimizeSourceToDependencyDirectives(Source, Out, Tokens));
+ EXPECT_STREQ("#include \"textual-header.h\"\nexport module m;\n"
+ "export import :l [[rename]];\n"
+ "import <<= 3;\nimport a b d e d e f e;\n"
+ "import foo [[no_unique_address]];\nimport foo();\n"
+ "import f(:sefse);\nimport f(->a = 3);\n", Out.data());
+ ASSERT_EQ(Tokens.size(), 12u);
+ EXPECT_EQ(Tokens[0].K,
+ minimize_source_to_dependency_directives::pp_include);
+ EXPECT_EQ(Tokens[2].K,
+ minimize_source_to_dependency_directives::cxx_module_decl);
+}
+
} // end anonymous namespace
More information about the cfe-commits
mailing list