Szelethus updated this revision to Diff 168334.

https://reviews.llvm.org/D52794

Files:
  lib/StaticAnalyzer/Core/PlistDiagnostics.cpp
  test/Analysis/Inputs/expected-plists/plist-macros-with-expansion.cpp.plist
  test/Analysis/plist-macros-with-expansion.cpp

Index: test/Analysis/plist-macros-with-expansion.cpp
===================================================================
--- test/Analysis/plist-macros-with-expansion.cpp
+++ test/Analysis/plist-macros-with-expansion.cpp
@@ -27,8 +27,8 @@
   *ptr = 5; // expected-warning{{Dereference of null pointer}}
 }
 
-// CHECK: <key>name</key><string></string>
-// CHECK: <key>expansion</key><string></string>
+// CHECK: <key>name</key><string>SET_PTR_VAR_TO_NULL</string>
+// CHECK: <key>expansion</key><string>ptr = 0 </string>
 
 #define NULL 0
 #define SET_PTR_VAR_TO_NULL_WITH_NESTED_MACRO \
@@ -40,5 +40,51 @@
   *ptr = 5; // expected-warning{{Dereference of null pointer}}
 }
 
-// CHECK: <key>name</key><string></string>
-// CHECK: <key>expansion</key><string></string>
+// CHECK: <key>name</key><string>SET_PTR_VAR_TO_NULL_WITH_NESTED_MACRO</string>
+// CHECK: <key>expansion</key><string>ptr = 0 </string>
+
+//===----------------------------------------------------------------------===//
+// Tests for function-like macro expansions.
+//===----------------------------------------------------------------------===//
+
+void setToNull(int **vptr) {
+  *vptr = nullptr;
+}
+
+#define TO_NULL(x) \
+  setToNull(x)
+
+void functionLikeMacroTest() {
+  int *ptr;
+  TO_NULL(&ptr);
+  *ptr = 5; // expected-warning{{Dereference of null pointer}}
+}
+
+// TODO: Expand argumnts.
+// CHECK: <key>name</key><string>TO_NULL</string>
+// CHECK: <key>expansion</key><string>setToNull ( x ) </string>
+
+#define DOES_NOTHING(x) \
+  {                     \
+    int b;              \
+    b = 5;              \
+  }                     \
+  print(x)
+
+#define DEREF(x)   \
+  DOES_NOTHING(x); \
+  *x
+
+void functionLikeNestedMacroTest() {
+  int *a;
+  TO_NULL(&a);
+  DEREF(a) = 5; // expected-warning{{Dereference of null pointer}}
+}
+
+// TODO: Expand argumnts.
+// CHECK: <key>name</key><string>TO_NULL</string>
+// CHECK: <key>expansion</key><string>setToNull ( x ) </string>
+
+// TODO: Expand argumnts.
+// CHECK: <key>name</key><string>DEREF</string>
+// CHECK: <key>expansion</key><string>{ int b ; b = 5 ; } print ( x ) ; * x </string>
Index: test/Analysis/Inputs/expected-plists/plist-macros-with-expansion.cpp.plist
===================================================================
--- test/Analysis/Inputs/expected-plists/plist-macros-with-expansion.cpp.plist
+++ test/Analysis/Inputs/expected-plists/plist-macros-with-expansion.cpp.plist
@@ -3,7 +3,7 @@
 <plist version="1.0">
 <dict>
  <key>clang_version</key>
-<string>clang version 8.0.0 (http://mainstream.inf.elte.hu/Szelethus/clang 80e1678b9f598ca78bb3b71cf546a63414a37b11) (https://github.com/llvm-mirror/llvm 1ffbf26a1a0a190d69327af875a3337b74a2ce82)</string>
+<string>clang version 8.0.0 (http://mainstream.inf.elte.hu/Szelethus/clang 54f58baf2c799080816023e7f78b92e4f9460078) (https://github.com/llvm-mirror/llvm 1ffbf26a1a0a190d69327af875a3337b74a2ce82)</string>
  <key>diagnostics</key>
  <array>
   <dict>
@@ -51,8 +51,8 @@
       <key>col</key><integer>3</integer>
       <key>file</key><integer>0</integer>
      </dict>
-     <key>name</key><string></string>
-     <key>expansion</key><string></string>
+     <key>name</key><string>SET_PTR_VAR_TO_NULL</string>
+     <key>expansion</key><string>ptr = 0 </string>
     </dict>
     <dict>
      <key>kind</key><string>event</string>
@@ -218,8 +218,8 @@
       <key>col</key><integer>3</integer>
       <key>file</key><integer>0</integer>
      </dict>
-     <key>name</key><string></string>
-     <key>expansion</key><string></string>
+     <key>name</key><string>SET_PTR_VAR_TO_NULL_WITH_NESTED_MACRO</string>
+     <key>expansion</key><string>ptr = 0 </string>
     </dict>
     <dict>
      <key>kind</key><string>event</string>
@@ -340,10 +340,537 @@
    </array>
   </dict>
   </dict>
+  <dict>
+   <key>path</key>
+   <array>
+    <dict>
+     <key>kind</key><string>control</string>
+     <key>edges</key>
+      <array>
+       <dict>
+        <key>start</key>
+         <array>
+          <dict>
+           <key>line</key><integer>58</integer>
+           <key>col</key><integer>3</integer>
+           <key>file</key><integer>0</integer>
+          </dict>
+          <dict>
+           <key>line</key><integer>58</integer>
+           <key>col</key><integer>5</integer>
+           <key>file</key><integer>0</integer>
+          </dict>
+         </array>
+        <key>end</key>
+         <array>
+          <dict>
+           <key>line</key><integer>59</integer>
+           <key>col</key><integer>3</integer>
+           <key>file</key><integer>0</integer>
+          </dict>
+          <dict>
+           <key>line</key><integer>59</integer>
+           <key>col</key><integer>9</integer>
+           <key>file</key><integer>0</integer>
+          </dict>
+         </array>
+       </dict>
+      </array>
+    </dict>
+    <dict>
+     <key>kind</key><string>macro_expansion</string>
+     <key>location</key>
+     <dict>
+      <key>line</key><integer>59</integer>
+      <key>col</key><integer>3</integer>
+      <key>file</key><integer>0</integer>
+     </dict>
+     <key>name</key><string>TO_NULL</string>
+     <key>expansion</key><string>setToNull ( x ) </string>
+    </dict>
+    <dict>
+     <key>kind</key><string>event</string>
+     <key>location</key>
+     <dict>
+      <key>line</key><integer>59</integer>
+      <key>col</key><integer>3</integer>
+      <key>file</key><integer>0</integer>
+     </dict>
+     <key>ranges</key>
+     <array>
+       <array>
+        <dict>
+         <key>line</key><integer>59</integer>
+         <key>col</key><integer>3</integer>
+         <key>file</key><integer>0</integer>
+        </dict>
+        <dict>
+         <key>line</key><integer>59</integer>
+         <key>col</key><integer>15</integer>
+         <key>file</key><integer>0</integer>
+        </dict>
+       </array>
+     </array>
+     <key>depth</key><integer>0</integer>
+     <key>extended_message</key>
+     <string>Calling &apos;setToNull&apos;</string>
+     <key>message</key>
+     <string>Calling &apos;setToNull&apos;</string>
+    </dict>
+    <dict>
+     <key>kind</key><string>event</string>
+     <key>location</key>
+     <dict>
+      <key>line</key><integer>50</integer>
+      <key>col</key><integer>1</integer>
+      <key>file</key><integer>0</integer>
+     </dict>
+     <key>depth</key><integer>1</integer>
+     <key>extended_message</key>
+     <string>Entered call from &apos;functionLikeMacroTest&apos;</string>
+     <key>message</key>
+     <string>Entered call from &apos;functionLikeMacroTest&apos;</string>
+    </dict>
+    <dict>
+     <key>kind</key><string>control</string>
+     <key>edges</key>
+      <array>
+       <dict>
+        <key>start</key>
+         <array>
+          <dict>
+           <key>line</key><integer>50</integer>
+           <key>col</key><integer>1</integer>
+           <key>file</key><integer>0</integer>
+          </dict>
+          <dict>
+           <key>line</key><integer>50</integer>
+           <key>col</key><integer>4</integer>
+           <key>file</key><integer>0</integer>
+          </dict>
+         </array>
+        <key>end</key>
+         <array>
+          <dict>
+           <key>line</key><integer>51</integer>
+           <key>col</key><integer>3</integer>
+           <key>file</key><integer>0</integer>
+          </dict>
+          <dict>
+           <key>line</key><integer>51</integer>
+           <key>col</key><integer>3</integer>
+           <key>file</key><integer>0</integer>
+          </dict>
+         </array>
+       </dict>
+      </array>
+    </dict>
+    <dict>
+     <key>kind</key><string>event</string>
+     <key>location</key>
+     <dict>
+      <key>line</key><integer>51</integer>
+      <key>col</key><integer>3</integer>
+      <key>file</key><integer>0</integer>
+     </dict>
+     <key>ranges</key>
+     <array>
+       <array>
+        <dict>
+         <key>line</key><integer>51</integer>
+         <key>col</key><integer>3</integer>
+         <key>file</key><integer>0</integer>
+        </dict>
+        <dict>
+         <key>line</key><integer>51</integer>
+         <key>col</key><integer>17</integer>
+         <key>file</key><integer>0</integer>
+        </dict>
+       </array>
+     </array>
+     <key>depth</key><integer>1</integer>
+     <key>extended_message</key>
+     <string>Null pointer value stored to &apos;ptr&apos;</string>
+     <key>message</key>
+     <string>Null pointer value stored to &apos;ptr&apos;</string>
+    </dict>
+    <dict>
+     <key>kind</key><string>event</string>
+     <key>location</key>
+     <dict>
+      <key>line</key><integer>59</integer>
+      <key>col</key><integer>3</integer>
+      <key>file</key><integer>0</integer>
+     </dict>
+     <key>ranges</key>
+     <array>
+       <array>
+        <dict>
+         <key>line</key><integer>59</integer>
+         <key>col</key><integer>3</integer>
+         <key>file</key><integer>0</integer>
+        </dict>
+        <dict>
+         <key>line</key><integer>59</integer>
+         <key>col</key><integer>15</integer>
+         <key>file</key><integer>0</integer>
+        </dict>
+       </array>
+     </array>
+     <key>depth</key><integer>0</integer>
+     <key>extended_message</key>
+     <string>Returning from &apos;setToNull&apos;</string>
+     <key>message</key>
+     <string>Returning from &apos;setToNull&apos;</string>
+    </dict>
+    <dict>
+     <key>kind</key><string>control</string>
+     <key>edges</key>
+      <array>
+       <dict>
+        <key>start</key>
+         <array>
+          <dict>
+           <key>line</key><integer>60</integer>
+           <key>col</key><integer>3</integer>
+           <key>file</key><integer>0</integer>
+          </dict>
+          <dict>
+           <key>line</key><integer>60</integer>
+           <key>col</key><integer>3</integer>
+           <key>file</key><integer>0</integer>
+          </dict>
+         </array>
+        <key>end</key>
+         <array>
+          <dict>
+           <key>line</key><integer>60</integer>
+           <key>col</key><integer>8</integer>
+           <key>file</key><integer>0</integer>
+          </dict>
+          <dict>
+           <key>line</key><integer>60</integer>
+           <key>col</key><integer>8</integer>
+           <key>file</key><integer>0</integer>
+          </dict>
+         </array>
+       </dict>
+      </array>
+    </dict>
+    <dict>
+     <key>kind</key><string>event</string>
+     <key>location</key>
+     <dict>
+      <key>line</key><integer>60</integer>
+      <key>col</key><integer>8</integer>
+      <key>file</key><integer>0</integer>
+     </dict>
+     <key>ranges</key>
+     <array>
+       <array>
+        <dict>
+         <key>line</key><integer>60</integer>
+         <key>col</key><integer>4</integer>
+         <key>file</key><integer>0</integer>
+        </dict>
+        <dict>
+         <key>line</key><integer>60</integer>
+         <key>col</key><integer>6</integer>
+         <key>file</key><integer>0</integer>
+        </dict>
+       </array>
+     </array>
+     <key>depth</key><integer>0</integer>
+     <key>extended_message</key>
+     <string>Dereference of null pointer (loaded from variable &apos;ptr&apos;)</string>
+     <key>message</key>
+     <string>Dereference of null pointer (loaded from variable &apos;ptr&apos;)</string>
+    </dict>
+   </array>
+   <key>description</key><string>Dereference of null pointer (loaded from variable &apos;ptr&apos;)</string>
+   <key>category</key><string>Logic error</string>
+   <key>type</key><string>Dereference of null pointer</string>
+   <key>check_name</key><string>core.NullDereference</string>
+   <!-- This hash is experimental and going to change! -->
+   <key>issue_hash_content_of_line_in_context</key><string>370a457744311752aac789447b4ef16c</string>
+  <key>issue_context_kind</key><string>function</string>
+  <key>issue_context</key><string>functionLikeMacroTest</string>
+  <key>issue_hash_function_offset</key><string>3</string>
+  <key>location</key>
+  <dict>
+   <key>line</key><integer>60</integer>
+   <key>col</key><integer>8</integer>
+   <key>file</key><integer>0</integer>
+  </dict>
+  <key>ExecutedLines</key>
+  <dict>
+   <key>0</key>
+   <array>
+    <integer>50</integer>
+    <integer>51</integer>
+    <integer>57</integer>
+    <integer>58</integer>
+    <integer>59</integer>
+    <integer>60</integer>
+   </array>
+  </dict>
+  </dict>
+  <dict>
+   <key>path</key>
+   <array>
+    <dict>
+     <key>kind</key><string>control</string>
+     <key>edges</key>
+      <array>
+       <dict>
+        <key>start</key>
+         <array>
+          <dict>
+           <key>line</key><integer>78</integer>
+           <key>col</key><integer>3</integer>
+           <key>file</key><integer>0</integer>
+          </dict>
+          <dict>
+           <key>line</key><integer>78</integer>
+           <key>col</key><integer>5</integer>
+           <key>file</key><integer>0</integer>
+          </dict>
+         </array>
+        <key>end</key>
+         <array>
+          <dict>
+           <key>line</key><integer>79</integer>
+           <key>col</key><integer>3</integer>
+           <key>file</key><integer>0</integer>
+          </dict>
+          <dict>
+           <key>line</key><integer>79</integer>
+           <key>col</key><integer>9</integer>
+           <key>file</key><integer>0</integer>
+          </dict>
+         </array>
+       </dict>
+      </array>
+    </dict>
+    <dict>
+     <key>kind</key><string>macro_expansion</string>
+     <key>location</key>
+     <dict>
+      <key>line</key><integer>79</integer>
+      <key>col</key><integer>3</integer>
+      <key>file</key><integer>0</integer>
+     </dict>
+     <key>name</key><string>TO_NULL</string>
+     <key>expansion</key><string>setToNull ( x ) </string>
+    </dict>
+    <dict>
+     <key>kind</key><string>event</string>
+     <key>location</key>
+     <dict>
+      <key>line</key><integer>79</integer>
+      <key>col</key><integer>3</integer>
+      <key>file</key><integer>0</integer>
+     </dict>
+     <key>ranges</key>
+     <array>
+       <array>
+        <dict>
+         <key>line</key><integer>79</integer>
+         <key>col</key><integer>3</integer>
+         <key>file</key><integer>0</integer>
+        </dict>
+        <dict>
+         <key>line</key><integer>79</integer>
+         <key>col</key><integer>13</integer>
+         <key>file</key><integer>0</integer>
+        </dict>
+       </array>
+     </array>
+     <key>depth</key><integer>0</integer>
+     <key>extended_message</key>
+     <string>Calling &apos;setToNull&apos;</string>
+     <key>message</key>
+     <string>Calling &apos;setToNull&apos;</string>
+    </dict>
+    <dict>
+     <key>kind</key><string>event</string>
+     <key>location</key>
+     <dict>
+      <key>line</key><integer>50</integer>
+      <key>col</key><integer>1</integer>
+      <key>file</key><integer>0</integer>
+     </dict>
+     <key>depth</key><integer>1</integer>
+     <key>extended_message</key>
+     <string>Entered call from &apos;functionLikeNestedMacroTest&apos;</string>
+     <key>message</key>
+     <string>Entered call from &apos;functionLikeNestedMacroTest&apos;</string>
+    </dict>
+    <dict>
+     <key>kind</key><string>control</string>
+     <key>edges</key>
+      <array>
+       <dict>
+        <key>start</key>
+         <array>
+          <dict>
+           <key>line</key><integer>50</integer>
+           <key>col</key><integer>1</integer>
+           <key>file</key><integer>0</integer>
+          </dict>
+          <dict>
+           <key>line</key><integer>50</integer>
+           <key>col</key><integer>4</integer>
+           <key>file</key><integer>0</integer>
+          </dict>
+         </array>
+        <key>end</key>
+         <array>
+          <dict>
+           <key>line</key><integer>51</integer>
+           <key>col</key><integer>3</integer>
+           <key>file</key><integer>0</integer>
+          </dict>
+          <dict>
+           <key>line</key><integer>51</integer>
+           <key>col</key><integer>3</integer>
+           <key>file</key><integer>0</integer>
+          </dict>
+         </array>
+       </dict>
+      </array>
+    </dict>
+    <dict>
+     <key>kind</key><string>event</string>
+     <key>location</key>
+     <dict>
+      <key>line</key><integer>51</integer>
+      <key>col</key><integer>3</integer>
+      <key>file</key><integer>0</integer>
+     </dict>
+     <key>ranges</key>
+     <array>
+       <array>
+        <dict>
+         <key>line</key><integer>51</integer>
+         <key>col</key><integer>3</integer>
+         <key>file</key><integer>0</integer>
+        </dict>
+        <dict>
+         <key>line</key><integer>51</integer>
+         <key>col</key><integer>17</integer>
+         <key>file</key><integer>0</integer>
+        </dict>
+       </array>
+     </array>
+     <key>depth</key><integer>1</integer>
+     <key>extended_message</key>
+     <string>Null pointer value stored to &apos;a&apos;</string>
+     <key>message</key>
+     <string>Null pointer value stored to &apos;a&apos;</string>
+    </dict>
+    <dict>
+     <key>kind</key><string>event</string>
+     <key>location</key>
+     <dict>
+      <key>line</key><integer>79</integer>
+      <key>col</key><integer>3</integer>
+      <key>file</key><integer>0</integer>
+     </dict>
+     <key>ranges</key>
+     <array>
+       <array>
+        <dict>
+         <key>line</key><integer>79</integer>
+         <key>col</key><integer>3</integer>
+         <key>file</key><integer>0</integer>
+        </dict>
+        <dict>
+         <key>line</key><integer>79</integer>
+         <key>col</key><integer>13</integer>
+         <key>file</key><integer>0</integer>
+        </dict>
+       </array>
+     </array>
+     <key>depth</key><integer>0</integer>
+     <key>extended_message</key>
+     <string>Returning from &apos;setToNull&apos;</string>
+     <key>message</key>
+     <string>Returning from &apos;setToNull&apos;</string>
+    </dict>
+    <dict>
+     <key>kind</key><string>macro_expansion</string>
+     <key>location</key>
+     <dict>
+      <key>line</key><integer>80</integer>
+      <key>col</key><integer>3</integer>
+      <key>file</key><integer>0</integer>
+     </dict>
+     <key>name</key><string>DEREF</string>
+     <key>expansion</key><string>{ int b ; b = 5 ; } print ( x ) ; * x </string>
+    </dict>
+    <dict>
+     <key>kind</key><string>event</string>
+     <key>location</key>
+     <dict>
+      <key>line</key><integer>80</integer>
+      <key>col</key><integer>12</integer>
+      <key>file</key><integer>0</integer>
+     </dict>
+     <key>ranges</key>
+     <array>
+       <array>
+        <dict>
+         <key>line</key><integer>80</integer>
+         <key>col</key><integer>3</integer>
+         <key>file</key><integer>0</integer>
+        </dict>
+        <dict>
+         <key>line</key><integer>80</integer>
+         <key>col</key><integer>10</integer>
+         <key>file</key><integer>0</integer>
+        </dict>
+       </array>
+     </array>
+     <key>depth</key><integer>0</integer>
+     <key>extended_message</key>
+     <string>Dereference of null pointer (loaded from variable &apos;a&apos;)</string>
+     <key>message</key>
+     <string>Dereference of null pointer (loaded from variable &apos;a&apos;)</string>
+    </dict>
+   </array>
+   <key>description</key><string>Dereference of null pointer (loaded from variable &apos;a&apos;)</string>
+   <key>category</key><string>Logic error</string>
+   <key>type</key><string>Dereference of null pointer</string>
+   <key>check_name</key><string>core.NullDereference</string>
+   <!-- This hash is experimental and going to change! -->
+   <key>issue_hash_content_of_line_in_context</key><string>873802674657bba4565f64c7bbf0ded9</string>
+  <key>issue_context_kind</key><string>function</string>
+  <key>issue_context</key><string>functionLikeNestedMacroTest</string>
+  <key>issue_hash_function_offset</key><string>3</string>
+  <key>location</key>
+  <dict>
+   <key>line</key><integer>80</integer>
+   <key>col</key><integer>12</integer>
+   <key>file</key><integer>0</integer>
+  </dict>
+  <key>ExecutedLines</key>
+  <dict>
+   <key>0</key>
+   <array>
+    <integer>50</integer>
+    <integer>51</integer>
+    <integer>77</integer>
+    <integer>78</integer>
+    <integer>79</integer>
+    <integer>80</integer>
+   </array>
+  </dict>
+  </dict>
  </array>
  <key>files</key>
  <array>
   <string>/home/eumakri/Documents/2codechecker_dev_env/llvm/tools/clang/test/Analysis/plist-macros-with-expansion.cpp</string>
  </array>
 </dict>
 </plist>
\ No newline at end of file
Index: lib/StaticAnalyzer/Core/PlistDiagnostics.cpp
===================================================================
--- lib/StaticAnalyzer/Core/PlistDiagnostics.cpp
+++ lib/StaticAnalyzer/Core/PlistDiagnostics.cpp
@@ -269,10 +269,7 @@
 } // end of anonymous namespace
 
 static ExpansionInfo getExpandedMacro(SourceLocation MacroLoc,
-                                      const Preprocessor &PP) {
-  // TODO: Implement macro expansion.
-  return { "", "" };
-}
+                                      const Preprocessor &PP);
 
 static void ReportMacro(raw_ostream &o,
                         const PathDiagnosticMacroPiece& P,
@@ -665,3 +662,121 @@
   // Finish.
   o << "</dict>\n</plist>";
 }
+
+//===----------------------------------------------------------------------===//
+// Helper functions and data structures for expanding macros.
+//===----------------------------------------------------------------------===//
+
+namespace {
+
+struct MacroNameAndInfo {
+  std::string Name;
+  const MacroInfo *MI = nullptr;
+
+  MacroNameAndInfo(std::string N, const MacroInfo *MI)
+    : Name(std::move(N)), MI(MI) {}
+};
+
+} // end of anonymous namespace
+
+/// Retrieves the name of the macro and its MacroInfo.
+static MacroNameAndInfo getMacroNameAndInfo(SourceLocation ExpanLoc,
+                                            const Preprocessor &PP);
+
+static ExpansionInfo getExpandedMacroImpl(SourceLocation MacroLoc,
+                                          const Preprocessor &PP) {
+
+  const SourceManager &SM = PP.getSourceManager();
+
+  MacroNameAndInfo Info = getMacroNameAndInfo(SM.getExpansionLoc(MacroLoc), PP);
+
+  std::string MacroName = std::move(Info.Name);
+  const MacroInfo *MI = Info.MI;
+
+  // Iterate over the macro's tokens and stringify them.
+  llvm::SmallString<200> ExpansionBuf;
+  llvm::raw_svector_ostream ExpansionOS(ExpansionBuf);
+
+  for (auto It = MI->tokens_begin(), E = MI->tokens_end(); It != E; ++It) {
+    Token T = *It;
+
+    if (T.is(tok::identifier)) {
+      const auto *II = T.getIdentifierInfo();
+      assert(II &&
+            "This token is an identifier but has no IdentifierInfo!");
+
+      // If this token is a macro that should be expanded inside the currect
+      // macro.
+      if (const MacroInfo *MI = PP.getMacroInfo(II)) {
+        ExpansionOS << getExpandedMacroImpl(T.getLocation(), PP)
+                         .Expansion;
+
+        // If this is a function-like macro, skip its arguments, as
+        // getExpandedMacro() already printed them.
+        if (MI->getNumParams() != 0) {
+          ++It;
+          assert(It->is(tok::l_paren) &&
+                 "This token should be '(' if the previous was a function-like "
+                 "macro!");
+
+          // Skip until we find the closing ')'.
+          int ParanthesesDepth = 1;
+          while (ParanthesesDepth != 0) {
+            ++It;
+
+            assert(It->isNot(tok::eof) &&
+                   "Encountered EOF while attempting to skip macro arguments!");
+            assert(It != E &&
+                   "End of the macro definition reached before finding ')'!");
+
+            if (It->is(tok::l_paren))
+              ++ParanthesesDepth;
+
+            if (It->is(tok::r_paren))
+              --ParanthesesDepth;
+          }
+        }
+        continue;
+      }
+    }
+
+    // If control reaches here, there's nothing left to do, print the token.
+    ExpansionOS << PP.getSpelling(T) + ' ';
+  }
+
+  return {MacroName, ExpansionOS.str()};
+}
+
+static ExpansionInfo getExpandedMacro(SourceLocation MacroLoc,
+                                      const Preprocessor &PP) {
+  return getExpandedMacroImpl(MacroLoc, PP);
+}
+
+static MacroNameAndInfo getMacroNameAndInfo(SourceLocation ExpanLoc,
+                                            const Preprocessor &PP) {
+
+  const SourceManager &SM = PP.getSourceManager();
+  const LangOptions &LangOpts = PP.getLangOpts();
+
+  // First, we create a Lexer to lex *at the expansion location* the tokens
+  // referring to the macro's name and its arguments.
+  std::pair<FileID, unsigned> LocInfo = SM.getDecomposedLoc(ExpanLoc);
+  const llvm::MemoryBuffer *MB = SM.getBuffer(LocInfo.first);
+  const char *MacroNameTokenPos = MB->getBufferStart() + LocInfo.second;
+
+  Lexer RawLexer(SM.getLocForStartOfFile(LocInfo.first), LangOpts,
+                 MB->getBufferStart(), MacroNameTokenPos, MB->getBufferEnd());
+
+  // Acquire the macro's name.
+  Token TheTok;
+  RawLexer.LexFromRawLexer(TheTok);
+
+  std::string MacroName = PP.getSpelling(TheTok);
+
+  const auto *II = PP.getIdentifierInfo(MacroName);
+  assert(II && "Failed to acquire the IndetifierInfo for the macro!");
+  const MacroInfo *MI = PP.getMacroInfo(II);
+  assert(MI && "This IdentifierInfo should refer to a macro!");
+
+  return { MacroName, MI };
+}
_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to