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