[clang] [clang][frontend] Make DumpModuleInfoAction emit the full macro (PR #85745)

Zhang Yi via cfe-commits cfe-commits at lists.llvm.org
Tue Mar 19 00:39:42 PDT 2024


https://github.com/zhanyi22333 created https://github.com/llvm/llvm-project/pull/85745

This PR works on the TODO `Emit the macro definition bodies completely`  in FrontendActions.cpp. Emiting the macro definition bodies completely can help user get more details about macro.

The beginning of macro-body string is get by MacroInfo definition location in SourceManager. Then it compute the macro-body string length by locate the '\n' but not '\\\n'. After that, the string is getted and reformmatted into one line. 
When cannot get the MacroInfo, it will only emit the name of macro definition. 

@rjmccall @kpneal @zahiraam @efriedma-quic @vgvassilev @junaire

>From d29678159c34a668259fbed601df975275190105 Mon Sep 17 00:00:00 2001
From: Zhang Yi <18994118902 at 163.com>
Date: Mon, 18 Mar 2024 20:22:39 -0700
Subject: [PATCH 1/2] [clang][frontend] change DumpModuleInfoAction test cases.

---
 clang/test/Modules/cxx20-module-file-info-macros.cpp | 8 ++++----
 1 file changed, 4 insertions(+), 4 deletions(-)

diff --git a/clang/test/Modules/cxx20-module-file-info-macros.cpp b/clang/test/Modules/cxx20-module-file-info-macros.cpp
index 3b67e9b9acd410..fad218bdfc9638 100644
--- a/clang/test/Modules/cxx20-module-file-info-macros.cpp
+++ b/clang/test/Modules/cxx20-module-file-info-macros.cpp
@@ -37,8 +37,8 @@
 
 // CHECK: Macro Definitions:
 // CHECK-DAG: REDEFINE
-// CHECK-DAG: FUNC_Macro
-// CHECK-DAG: CONSTANT
+// CHECK-DAG: FUNC_Macro(X) (X+1)
+// CHECK-DAG: CONSTANT 43
 // CHECK-DAG: FOO
 // CHECK-NEXT: ===
 
@@ -46,8 +46,8 @@
 #include "foo.h"
 #undef REDEFINE
 // CHECK: Macro Definitions:
-// CHECK-DAG: CONSTANT
-// CHECK-DAG: FUNC_Macro
+// CHECK-DAG: CONSTANT 43
+// CHECK-DAG: FUNC_Macro(X) (X+1)
 // CHECK-DAG: FOO
 // CHECK-NEXT: ===
 

>From ce6501638142a9cbce7733ff9acab70f82d65891 Mon Sep 17 00:00:00 2001
From: Zhang Yi <18994118902 at 163.com>
Date: Mon, 18 Mar 2024 20:23:00 -0700
Subject: [PATCH 2/2] [clang][frontend] Make DumpModuleInfoAction emit the full
 macro

---
 clang/lib/Frontend/FrontendActions.cpp | 32 +++++++++++++++++++++++---
 1 file changed, 29 insertions(+), 3 deletions(-)

diff --git a/clang/lib/Frontend/FrontendActions.cpp b/clang/lib/Frontend/FrontendActions.cpp
index 81fcd8d5ae9bd3..aa2781daef3988 100644
--- a/clang/lib/Frontend/FrontendActions.cpp
+++ b/clang/lib/Frontend/FrontendActions.cpp
@@ -925,15 +925,41 @@ void DumpModuleInfoAction::ExecuteAction() {
 
     // Emit the macro definitions in the module file so that we can know how
     // much definitions in the module file quickly.
-    // TODO: Emit the macro definition bodies completely.
     if (auto FilteredMacros = llvm::make_filter_range(
             R->getPreprocessor().macros(),
             [](const auto &Macro) { return Macro.first->isFromAST(); });
         !FilteredMacros.empty()) {
       Out << "   Macro Definitions:\n";
       for (/*<IdentifierInfo *, MacroState> pair*/ const auto &Macro :
-           FilteredMacros)
-        Out << "     " << Macro.first->getName() << "\n";
+           FilteredMacros) {
+        SourceManager &SM = PP.getSourceManager();
+        clang::MacroInfo *MacroInfo = PP.getMacroInfo(Macro.first);
+        if (MacroInfo) {
+          bool isInvalid=true;
+          const char* ContentStrPtr=SM.getCharacterData(MacroInfo->getDefinitionLoc(),&isInvalid);
+          if (!isInvalid) {
+          int ContentLength=0;
+          while ( !(*(ContentStrPtr+ContentLength)=='\n') ||  *(ContentStrPtr+ContentLength-1)=='\\') {
+            ContentLength++;
+          }
+          std::string MacroContent=std::string(ContentStrPtr,ContentLength);
+          // Replace '\\\n' with space
+          size_t pos = 0;
+          while ((pos = MacroContent.find("\\\n", pos)) != std::string::npos) {
+            MacroContent.replace(pos, 2," ");
+          }
+          // Merge spaces
+          auto new_end = std::unique(MacroContent.begin(), MacroContent.end(), [](char a, char b) {
+            return a == ' ' && b == ' ';
+          });
+          MacroContent.erase(new_end, MacroContent.end());
+          Out << "     " << MacroContent << '\n';
+          }
+        }
+        else {
+          Out << "     " << Macro.first->getName() << "\n";
+        }
+      }
     }
 
     // Now let's print out any modules we did not see as part of the Primary.



More information about the cfe-commits mailing list