Szelethus updated this revision to Diff 171532.
Szelethus added a comment.
This revision is now accepted and ready to land.

Changes according to my last comment.


https://reviews.llvm.org/D52742

Files:
  include/clang/StaticAnalyzer/Core/AnalyzerOptions.h
  lib/StaticAnalyzer/Core/AnalyzerOptions.cpp
  lib/StaticAnalyzer/Core/BugReporter.cpp
  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
===================================================================
--- /dev/null
+++ test/Analysis/plist-macros-with-expansion.cpp
@@ -0,0 +1,44 @@
+// RUN: %clang_analyze_cc1 -analyzer-checker=core -verify %s
+//
+// RUN: %clang_analyze_cc1 -analyzer-checker=core %s  \
+// RUN:   -analyzer-output=plist -o %t.plist \
+// RUN:   -analyzer-config expand-macros=true
+//
+// Check the actual plist output.
+//   RUN: cat %t.plist | %diff_plist \
+//   RUN:   %S/Inputs/expected-plists/plist-macros-with-expansion.cpp.plist
+//
+// Check the macro expansions from the plist output here, to make the test more
+// understandable.
+//   RUN: FileCheck --input-file=%t.plist %s
+
+void print(const void*);
+
+//===----------------------------------------------------------------------===//
+// Tests for non-function-like macro expansions.
+//===----------------------------------------------------------------------===//
+
+#define SET_PTR_VAR_TO_NULL \
+  ptr = 0
+
+void nonFunctionLikeMacroTest() {
+  int *ptr;
+  SET_PTR_VAR_TO_NULL;
+  *ptr = 5; // expected-warning{{Dereference of null pointer}}
+}
+
+// CHECK: <key>name</key><string></string>
+// CHECK-NEXT: <key>expansion</key><string></string>
+
+#define NULL 0
+#define SET_PTR_VAR_TO_NULL_WITH_NESTED_MACRO \
+  ptr = NULL
+
+void nonFunctionLikeNestedMacroTest() {
+  int *ptr;
+  SET_PTR_VAR_TO_NULL_WITH_NESTED_MACRO;
+  *ptr = 5; // expected-warning{{Dereference of null pointer}}
+}
+
+// CHECK: <key>name</key><string></string>
+// CHECK-NEXT: <key>expansion</key><string></string>
Index: test/Analysis/Inputs/expected-plists/plist-macros-with-expansion.cpp.plist
===================================================================
--- /dev/null
+++ test/Analysis/Inputs/expected-plists/plist-macros-with-expansion.cpp.plist
@@ -0,0 +1,353 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE plist PUBLIC "-//Apple Computer//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd";>
+<plist version="1.0">
+<dict>
+ <key>clang_version</key>
+<string>clang version 8.0.0 (http://mainstream.inf.elte.hu/Szelethus/clang e0f3a71311657c25ac9844d8124f1564353487ca) (https://github.com/llvm-mirror/llvm 5973d705524e5432b05634a9aab38ecd2360ff13)</string>
+ <key>diagnostics</key>
+ <array>
+  <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>25</integer>
+           <key>col</key><integer>3</integer>
+           <key>file</key><integer>0</integer>
+          </dict>
+          <dict>
+           <key>line</key><integer>25</integer>
+           <key>col</key><integer>5</integer>
+           <key>file</key><integer>0</integer>
+          </dict>
+         </array>
+        <key>end</key>
+         <array>
+          <dict>
+           <key>line</key><integer>26</integer>
+           <key>col</key><integer>3</integer>
+           <key>file</key><integer>0</integer>
+          </dict>
+          <dict>
+           <key>line</key><integer>26</integer>
+           <key>col</key><integer>21</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>26</integer>
+      <key>col</key><integer>3</integer>
+      <key>file</key><integer>0</integer>
+     </dict>
+     <key>ranges</key>
+     <array>
+       <array>
+        <dict>
+         <key>line</key><integer>26</integer>
+         <key>col</key><integer>3</integer>
+         <key>file</key><integer>0</integer>
+        </dict>
+        <dict>
+         <key>line</key><integer>26</integer>
+         <key>col</key><integer>21</integer>
+         <key>file</key><integer>0</integer>
+        </dict>
+       </array>
+     </array>
+     <key>depth</key><integer>0</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>control</string>
+     <key>edges</key>
+      <array>
+       <dict>
+        <key>start</key>
+         <array>
+          <dict>
+           <key>line</key><integer>27</integer>
+           <key>col</key><integer>3</integer>
+           <key>file</key><integer>0</integer>
+          </dict>
+          <dict>
+           <key>line</key><integer>27</integer>
+           <key>col</key><integer>3</integer>
+           <key>file</key><integer>0</integer>
+          </dict>
+         </array>
+        <key>end</key>
+         <array>
+          <dict>
+           <key>line</key><integer>27</integer>
+           <key>col</key><integer>8</integer>
+           <key>file</key><integer>0</integer>
+          </dict>
+          <dict>
+           <key>line</key><integer>27</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>27</integer>
+      <key>col</key><integer>8</integer>
+      <key>file</key><integer>0</integer>
+     </dict>
+     <key>ranges</key>
+     <array>
+       <array>
+        <dict>
+         <key>line</key><integer>27</integer>
+         <key>col</key><integer>4</integer>
+         <key>file</key><integer>0</integer>
+        </dict>
+        <dict>
+         <key>line</key><integer>27</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>macro_expansions</key>
+   <array>
+    <dict>
+     <key>location</key>
+     <dict>
+      <key>line</key><integer>26</integer>
+      <key>col</key><integer>3</integer>
+      <key>file</key><integer>0</integer>
+     </dict>
+     <key>name</key><string></string>
+     <key>expansion</key><string></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>f8fbc46cc5afbb056d92bd3d3d702781</string>
+  <key>issue_context_kind</key><string>function</string>
+  <key>issue_context</key><string>nonFunctionLikeMacroTest</string>
+  <key>issue_hash_function_offset</key><string>3</string>
+  <key>location</key>
+  <dict>
+   <key>line</key><integer>27</integer>
+   <key>col</key><integer>8</integer>
+   <key>file</key><integer>0</integer>
+  </dict>
+  <key>ExecutedLines</key>
+  <dict>
+   <key>0</key>
+   <array>
+    <integer>24</integer>
+    <integer>25</integer>
+    <integer>26</integer>
+    <integer>27</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>38</integer>
+           <key>col</key><integer>3</integer>
+           <key>file</key><integer>0</integer>
+          </dict>
+          <dict>
+           <key>line</key><integer>38</integer>
+           <key>col</key><integer>5</integer>
+           <key>file</key><integer>0</integer>
+          </dict>
+         </array>
+        <key>end</key>
+         <array>
+          <dict>
+           <key>line</key><integer>39</integer>
+           <key>col</key><integer>3</integer>
+           <key>file</key><integer>0</integer>
+          </dict>
+          <dict>
+           <key>line</key><integer>39</integer>
+           <key>col</key><integer>39</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>39</integer>
+      <key>col</key><integer>3</integer>
+      <key>file</key><integer>0</integer>
+     </dict>
+     <key>ranges</key>
+     <array>
+       <array>
+        <dict>
+         <key>line</key><integer>39</integer>
+         <key>col</key><integer>3</integer>
+         <key>file</key><integer>0</integer>
+        </dict>
+        <dict>
+         <key>line</key><integer>39</integer>
+         <key>col</key><integer>39</integer>
+         <key>file</key><integer>0</integer>
+        </dict>
+       </array>
+     </array>
+     <key>depth</key><integer>0</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>control</string>
+     <key>edges</key>
+      <array>
+       <dict>
+        <key>start</key>
+         <array>
+          <dict>
+           <key>line</key><integer>40</integer>
+           <key>col</key><integer>3</integer>
+           <key>file</key><integer>0</integer>
+          </dict>
+          <dict>
+           <key>line</key><integer>40</integer>
+           <key>col</key><integer>3</integer>
+           <key>file</key><integer>0</integer>
+          </dict>
+         </array>
+        <key>end</key>
+         <array>
+          <dict>
+           <key>line</key><integer>40</integer>
+           <key>col</key><integer>8</integer>
+           <key>file</key><integer>0</integer>
+          </dict>
+          <dict>
+           <key>line</key><integer>40</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>40</integer>
+      <key>col</key><integer>8</integer>
+      <key>file</key><integer>0</integer>
+     </dict>
+     <key>ranges</key>
+     <array>
+       <array>
+        <dict>
+         <key>line</key><integer>40</integer>
+         <key>col</key><integer>4</integer>
+         <key>file</key><integer>0</integer>
+        </dict>
+        <dict>
+         <key>line</key><integer>40</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>macro_expansions</key>
+   <array>
+    <dict>
+     <key>location</key>
+     <dict>
+      <key>line</key><integer>39</integer>
+      <key>col</key><integer>3</integer>
+      <key>file</key><integer>0</integer>
+     </dict>
+     <key>name</key><string></string>
+     <key>expansion</key><string></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>d5eba61193b41c27fc7b2705cbd607ba</string>
+  <key>issue_context_kind</key><string>function</string>
+  <key>issue_context</key><string>nonFunctionLikeNestedMacroTest</string>
+  <key>issue_hash_function_offset</key><string>3</string>
+  <key>location</key>
+  <dict>
+   <key>line</key><integer>40</integer>
+   <key>col</key><integer>8</integer>
+   <key>file</key><integer>0</integer>
+  </dict>
+  <key>ExecutedLines</key>
+  <dict>
+   <key>0</key>
+   <array>
+    <integer>37</integer>
+    <integer>38</integer>
+    <integer>39</integer>
+    <integer>40</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
@@ -72,6 +72,7 @@
   const FIDMap& FM;
   AnalyzerOptions &AnOpts;
   const Preprocessor &PP;
+  llvm::SmallVector<const PathDiagnosticMacroPiece *, 0> MacroPieces;
 
 public:
   PlistPrinter(const FIDMap& FM, AnalyzerOptions &AnOpts,
@@ -86,6 +87,14 @@
     (void)AnOpts;
   }
 
+  /// Print the expansions of the collected macro pieces.
+  ///
+  /// Each time ReportDiag is called on a PathDiagnosticMacroPiece (or, if one
+  /// is found through a call piece, etc), it's subpieces are reported, and the
+  /// piece itself is collected. Call this function after the entire bugpath
+  /// was reported.
+  void ReportMacroExpansions(raw_ostream &o, unsigned indent);
+
 private:
   void ReportPiece(raw_ostream &o, const PathDiagnosticPiece &P,
                    unsigned indent, unsigned depth, bool includeControlFlow,
@@ -104,7 +113,8 @@
                     isKeyEvent);
         break;
       case PathDiagnosticPiece::Macro:
-        ReportMacro(o, cast<PathDiagnosticMacroPiece>(P), indent, depth);
+        ReportMacroSubPieces(o, cast<PathDiagnosticMacroPiece>(P), indent,
+                             depth);
         break;
       case PathDiagnosticPiece::Note:
         ReportNote(o, cast<PathDiagnosticNotePiece>(P), indent);
@@ -123,14 +133,25 @@
                    unsigned indent, unsigned depth, bool isKeyEvent = false);
   void ReportCall(raw_ostream &o, const PathDiagnosticCallPiece &P,
                   unsigned indent, unsigned depth);
-  void ReportMacro(raw_ostream &o, const PathDiagnosticMacroPiece& P,
-                   unsigned indent, unsigned depth);
+  void ReportMacroSubPieces(raw_ostream &o, const PathDiagnosticMacroPiece& P,
+                            unsigned indent, unsigned depth);
   void ReportNote(raw_ostream &o, const PathDiagnosticNotePiece& P,
                   unsigned indent);
 };
 
 } // end of anonymous namespace
 
+namespace {
+
+struct ExpansionInfo {
+  std::string MacroName;
+  std::string Expansion;
+  ExpansionInfo(std::string N, std::string E)
+    : MacroName(std::move(N)), Expansion(std::move(E)) {}
+};
+
+} // end of anonymous namespace
+
 static void printBugPath(llvm::raw_ostream &o, const FIDMap& FM,
                          AnalyzerOptions &AnOpts,
                          const Preprocessor &PP,
@@ -143,6 +164,10 @@
                           SmallVectorImpl<FileID> &Fids,
                           FIDMap &FM,
                           llvm::raw_fd_ostream &o);
+
+static ExpansionInfo getExpandedMacro(SourceLocation MacroLoc,
+                                      const Preprocessor &PP);
+
 //===----------------------------------------------------------------------===//
 // Methods of PlistPrinter.
 //===----------------------------------------------------------------------===//
@@ -299,16 +324,52 @@
     ReportPiece(o, *callExit, indent, depth, /*includeControlFlow*/ true);
 }
 
-void PlistPrinter::ReportMacro(raw_ostream &o,
-                               const PathDiagnosticMacroPiece& P,
-                               unsigned indent, unsigned depth) {
+void PlistPrinter::ReportMacroSubPieces(raw_ostream &o,
+                                        const PathDiagnosticMacroPiece& P,
+                                        unsigned indent, unsigned depth) {
+  MacroPieces.push_back(&P);
 
-  for (PathPieces::const_iterator I = P.subPieces.begin(), E=P.subPieces.end();
-       I!=E; ++I) {
+  for (PathPieces::const_iterator I = P.subPieces.begin(),
+                                  E = P.subPieces.end();
+       I != E; ++I) {
     ReportPiece(o, **I, indent, depth, /*includeControlFlow*/ false);
   }
 }
 
+void PlistPrinter::ReportMacroExpansions(raw_ostream &o, unsigned indent) {
+
+  for (const PathDiagnosticMacroPiece *P : MacroPieces) {
+    const SourceManager &SM = PP.getSourceManager();
+    ExpansionInfo EI = getExpandedMacro(P->getLocation().asLocation(), PP);
+
+    Indent(o, indent) << "<dict>\n";
+    ++indent;
+
+    // Output the location.
+    FullSourceLoc L = P->getLocation().asLocation();
+
+    Indent(o, indent) << "<key>location</key>\n";
+    EmitLocation(o, SM, L, FM, indent);
+
+    // Output the ranges (if any).
+    ArrayRef<SourceRange> Ranges = P->getRanges();
+    EmitRanges(o, Ranges, indent);
+
+    // Output the macro name.
+    Indent(o, indent) << "<key>name</key>";
+    EmitString(o, EI.MacroName) << '\n';
+
+    // Output what it expands into.
+    Indent(o, indent) << "<key>expansion</key>";
+    EmitString(o, EI.Expansion) << '\n';
+
+    // Finish up.
+    --indent;
+    Indent(o, indent);
+    o << "</dict>\n";
+  }
+}
+
 void PlistPrinter::ReportNote(raw_ostream &o, const PathDiagnosticNotePiece& P,
                               unsigned indent) {
 
@@ -339,6 +400,12 @@
 // Static function definitions.
 //===----------------------------------------------------------------------===//
 
+static ExpansionInfo getExpandedMacro(SourceLocation MacroLoc,
+                                      const Preprocessor &PP) {
+  // TODO: Implement macro expansion.
+  return { "", "" };
+}
+
 /// Print coverage information to output stream {@code o}.
 /// May modify the used list of files {@code Fids} by inserting new ones.
 static void printCoverage(const PathDiagnostic *D,
@@ -408,6 +475,14 @@
     Printer.ReportDiag(o, **I);
 
   o << "   </array>\n";
+
+  if (!AnOpts.shouldDisplayMacroExpansions())
+    return;
+
+  o << "   <key>macro_expansions</key>\n"
+       "   <array>\n";
+  Printer.ReportMacroExpansions(o, /* indent */ 4);
+  o << "   </array>\n";
 }
 
 //===----------------------------------------------------------------------===//
Index: lib/StaticAnalyzer/Core/BugReporter.cpp
===================================================================
--- lib/StaticAnalyzer/Core/BugReporter.cpp
+++ lib/StaticAnalyzer/Core/BugReporter.cpp
@@ -546,7 +546,8 @@
   }
 }
 
-static void CompactPathDiagnostic(PathPieces &path, const SourceManager& SM);
+static void CompactMacroExpandedPieces(PathPieces &path,
+                                       const SourceManager& SM);
 
 
 std::shared_ptr<PathDiagnosticControlFlowPiece> generateDiagForSwitchOP(
@@ -1972,8 +1973,6 @@
                   PathDiagnosticLocation::createBegin(D, SM));
   }
 
-  if (!AddPathEdges && GenerateDiagnostics)
-    CompactPathDiagnostic(PD->getMutablePieces(), SM);
 
   // Finally, prune the diagnostic path of uninteresting stuff.
   if (!PD->path.empty()) {
@@ -2007,6 +2006,10 @@
     removeRedundantMsgs(PD->getMutablePieces());
     removeEdgesToDefaultInitializers(PD->getMutablePieces());
   }
+
+  if (GenerateDiagnostics && Opts.shouldDisplayMacroExpansions())
+    CompactMacroExpandedPieces(PD->getMutablePieces(), SM);
+
   return PD;
 }
 
@@ -2436,9 +2439,10 @@
   return true;
 }
 
-/// CompactPathDiagnostic - This function postprocesses a PathDiagnostic object
-///  and collapses PathDiagosticPieces that are expanded by macros.
-static void CompactPathDiagnostic(PathPieces &path, const SourceManager& SM) {
+/// CompactMacroExpandedPieces - This function postprocesses a PathDiagnostic
+/// object and collapses PathDiagosticPieces that are expanded by macros.
+static void CompactMacroExpandedPieces(PathPieces &path,
+                                       const SourceManager& SM) {
   using MacroStackTy =
       std::vector<
           std::pair<std::shared_ptr<PathDiagnosticMacroPiece>, SourceLocation>>;
@@ -2454,7 +2458,7 @@
 
     // Recursively compact calls.
     if (auto *call = dyn_cast<PathDiagnosticCallPiece>(&*piece)) {
-      CompactPathDiagnostic(call->path, SM);
+      CompactMacroExpandedPieces(call->path, SM);
     }
 
     // Get the location of the PathDiagnosticPiece.
Index: lib/StaticAnalyzer/Core/AnalyzerOptions.cpp
===================================================================
--- lib/StaticAnalyzer/Core/AnalyzerOptions.cpp
+++ lib/StaticAnalyzer/Core/AnalyzerOptions.cpp
@@ -465,6 +465,13 @@
   return DisplayNotesAsEvents.getValue();
 }
 
+bool AnalyzerOptions::shouldDisplayMacroExpansions() {
+  if (!DisplayMacroExpansions.hasValue())
+    DisplayMacroExpansions =
+        getBooleanOption("expand-macros", /*Default=*/false);
+  return DisplayMacroExpansions.getValue();
+}
+
 bool AnalyzerOptions::shouldAggressivelySimplifyBinaryOperation() {
   if (!AggressiveBinaryOperationSimplification.hasValue())
     AggressiveBinaryOperationSimplification =
Index: include/clang/StaticAnalyzer/Core/AnalyzerOptions.h
===================================================================
--- include/clang/StaticAnalyzer/Core/AnalyzerOptions.h
+++ include/clang/StaticAnalyzer/Core/AnalyzerOptions.h
@@ -312,6 +312,9 @@
   /// \sa shouldDisplayNotesAsEvents
   Optional<bool> DisplayNotesAsEvents;
 
+  /// \sa shouldDisplayMacroExpansions
+  Optional<bool> DisplayMacroExpansions;
+
   /// \sa shouldAggressivelySimplifyBinaryOperation
   Optional<bool> AggressiveBinaryOperationSimplification;
 
@@ -687,6 +690,13 @@
   /// to false when unset.
   bool shouldDisplayNotesAsEvents();
 
+  /// Returns true if macros related to the bugpath should be expanded and
+  /// included in the plist output.
+  ///
+  /// This is controlled by the 'expand-macros' option, which defaults to false
+  /// when unset.
+  bool shouldDisplayMacroExpansions();
+
   /// Returns true if SValBuilder should rearrange comparisons and additive
   /// operations of symbolic expressions which consist of a sum of a symbol and
   /// a concrete integer into the format where symbols are on the left-hand
_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to