Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add "-M" and "-MM" command line options #312

Open
mingodad opened this issue Dec 31, 2023 · 2 comments
Open

Add "-M" and "-MM" command line options #312

mingodad opened this issue Dec 31, 2023 · 2 comments

Comments

@mingodad
Copy link

To help debug I propose to add -M and -MM command line options, I already got an MVP partially working (it's missing extract the filename without path and extension to use as root dependency like src/test.cpp -> test.o and check the last entry in the loop to omit the line continuation), see bellow .

Or maybe drop the line continuation and root dependency and simple dump the filenames.

--------------------------- src/frontend/cxx/cli.cc ---------------------------
index a2f9aa8..795cd68 100644
@@ -132,6 +132,12 @@ std::vector<CLIOptionDescr> options{
     {"-dM", "Print macro definitions in -E mode instead of normal output",
      &CLI::opt_dM},
 
+    {"-M", "Print dependencies of the main source file",
+     &CLI::opt_M},
+
+    {"-MM", "Print dependencies of the main source file, excluding system path",
+     &CLI::opt_MM},
+
     {"-S", "Only run preprocess and compilation steps", &CLI::opt_S,
      CLIOptionVisibility::kExperimental},
 

---------------------------- src/frontend/cxx/cli.h ----------------------------
index 6c7d61e..9c7ec57 100644
@@ -54,6 +54,8 @@ class CLI {
   bool opt_ast_dump = false;
   bool opt_ir_dump = false;
   bool opt_dM = false;
+  bool opt_MM = false;
+  bool opt_M = false;
   bool opt_dump_symbols = false;
   bool opt_dump_tokens = false;
   bool opt_E = false;

------------------------- src/frontend/cxx/frontend.cc -------------------------
index 2197050..d51809b 100644
@@ -238,7 +238,7 @@ auto runOnFile(const CLI& cli, const std::string& fileName) -> bool {
   }
 
   if (auto source = readAll(fileName)) {
-    if (cli.opt_E && !cli.opt_dM) {
+    if (cli.opt_E && !(cli.opt_dM || cli.opt_M || cli.opt_MM)) {
       preprocesor->preprocess(std::move(*source), fileName, output);
       shouldExit = true;
     } else {
@@ -247,6 +247,12 @@ auto runOnFile(const CLI& cli, const std::string& fileName) -> bool {
       if (cli.opt_dM) {
         preprocesor->printMacros(output);
         shouldExit = true;
+      } else if (cli.opt_M) {
+        preprocesor->printDependencies(output, false);
+        shouldExit = true;
+      } else if (cli.opt_MM) {
+        preprocesor->printDependencies(output, true);
+        shouldExit = true;
       } else if (cli.opt_dump_tokens) {
         dumpTokens(cli, unit, output);
         shouldExit = true;

------------------------ src/parser/cxx/preprocessor.cc ------------------------
index 7fc45d0..dbc26d3 100644
@@ -556,6 +556,7 @@ struct Preprocessor::Private {
     if (sourceFiles_.size() >= 4096) {
       cxx_runtime_error("too many source files");
     }
+    //std::cout << "createSourceFile: " << fileName << std::endl;
 
     const int sourceFileId = static_cast<int>(sourceFiles_.size() + 1);
 
@@ -2262,6 +2263,22 @@ void Preprocessor::printMacros(std::ostream &out) const {
   }
 }
 
+void Preprocessor::printDependencies(std::ostream &out, bool noSysPath) const {
+  for (const auto &sourceFile : d->sourceFiles_) {
+    if (noSysPath) {
+      bool isSysPath = false; 
+      for (const auto &sysPath : d->systemIncludePaths_) {
+        if (sourceFile->fileName.find(sysPath) == 0) {
+          isSysPath = true;
+          break;
+        }
+      }
+      if (isSysPath) continue;
+    }
+    out << cxx::format(" {} \\\n", sourceFile->fileName);
+  }
+}
+
 void Preprocessor::getTokenStartPosition(const Token &token, unsigned *line,
                                          unsigned *column,
                                          std::string_view *fileName) const {

------------------------ src/parser/cxx/preprocessor.h ------------------------
index 5585be5..89938a0 100644
@@ -97,6 +97,8 @@ class Preprocessor {
 
   void printMacros(std::ostream &out) const;
 
+  void printDependencies(std::ostream &out, bool noSysPath) const;
+
   void getTokenStartPosition(const Token &token, unsigned *line,
                              unsigned *column,
                              std::string_view *fileName) const;
@mingodad
Copy link
Author

I finished my MVP and the output matches the clang output (gcc too although gcc uses one space and clang uses two to at the beginning of each filename dependency) see here #313 .

@mingodad
Copy link
Author

This is my first step on a more ambitious feature that would dump each included file and show some stats about the context about it:

  • List of external referenced macros and it's values before include
  • List of external referenced macros changed (updated/deleted) after include
  • List of created macros after include

The idea is also to check if a giving file is attempted to be included more that once globally and if it has #pragma once or guard macro and the external referenced macro values have changed since it's first inclusion emit a warning/error .

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant