[PATCH] Add debug method to visualize complex source locations

Manuel Klimek klimek at google.com
Thu May 23 02:17:02 PDT 2013


  Use indent and rework math.

http://llvm-reviews.chandlerc.com/D768

CHANGE SINCE LAST DIFF
  http://llvm-reviews.chandlerc.com/D768?vs=2063&id=2081#toc

Files:
  include/clang/Basic/SourceLocation.h
  lib/Basic/SourceLocation.cpp

Index: include/clang/Basic/SourceLocation.h
===================================================================
--- include/clang/Basic/SourceLocation.h
+++ include/clang/Basic/SourceLocation.h
@@ -16,6 +16,7 @@
 #define LLVM_CLANG_SOURCELOCATION_H
 
 #include "clang/Basic/LLVM.h"
+#include "llvm/ADT/Twine.h"
 #include "llvm/Support/Compiler.h"
 #include "llvm/Support/PointerLikeTypeTraits.h"
 #include <cassert>
@@ -174,6 +175,9 @@
   void print(raw_ostream &OS, const SourceManager &SM) const;
   LLVM_ATTRIBUTE_USED std::string printToString(const SourceManager &SM) const;
   void dump(const SourceManager &SM) const;
+  LLVM_ATTRIBUTE_USED std::string printTreeToString(const SourceManager &SM,
+                                                    bool PrintCode = true,
+                                                    Twine IndentStr = "") const;
 };
 
 inline bool operator==(const SourceLocation &LHS, const SourceLocation &RHS) {
Index: lib/Basic/SourceLocation.cpp
===================================================================
--- lib/Basic/SourceLocation.cpp
+++ lib/Basic/SourceLocation.cpp
@@ -61,6 +61,55 @@
   OS << '>';
 }
 
+static void printSourceLocationContext(const SourceManager &SM,
+                                       SourceLocation Loc,
+                                       llvm::raw_ostream &OS,
+                                       Twine IndentStr) {
+  std::pair<FileID, unsigned> LocInfo = SM.getDecomposedSpellingLoc(Loc);
+  StringRef Buffer = SM.getBufferData(LocInfo.first);
+  size_t PreviousNewline = Buffer.rfind('\n', LocInfo.second);
+  size_t First = (PreviousNewline != StringRef::npos ? PreviousNewline + 1 : 0);
+  size_t NextNewline = Buffer.find('\n', LocInfo.second);
+  size_t Last = (NextNewline != StringRef::npos ? NextNewline : Buffer.size());
+  OS << "|" << Buffer.substr(First, Last - First) << "|\n" << IndentStr;
+  OS.indent(1 + LocInfo.second - First) << "^ ";
+}
+
+std::string SourceLocation::printTreeToString(const SourceManager &SM,
+                                              bool PrintCode,
+                                              Twine IndentStr) const {
+  std::string S;
+  llvm::raw_string_ostream OS(S);
+  if (!isValid() || !isMacroID()) {
+    if (PrintCode)
+      printSourceLocationContext(SM, *this, OS, IndentStr + "               ");
+    OS << printToString(SM);
+  } else {
+    SourceLocation SpellingLoc = SM.getImmediateSpellingLoc(*this);
+    std::pair<SourceLocation, SourceLocation> ExpansionLoc =
+        SM.getImmediateExpansionRange(*this);
+    if (IndentStr.str().empty())
+      OS << "Loc";
+    OS << "\n";
+    if (ExpansionLoc.first != ExpansionLoc.second) {
+      OS << IndentStr << "|-"
+         << "ExpansionStart " << ExpansionLoc.first.printTreeToString(
+                                     SM, PrintCode, IndentStr + "| ") << ",\n"
+         << IndentStr << "|-"
+         << "ExpansionEnd   " << ExpansionLoc.second.printTreeToString(
+                                     SM, PrintCode, IndentStr + "| ") << ",\n";
+    } else {
+      OS << IndentStr << "|-"
+         << "Expansion      " << ExpansionLoc.first.printTreeToString(
+                                     SM, PrintCode, IndentStr + "| ") << ",\n";
+    }
+    OS << IndentStr << "`-"
+       << "Spelling       "
+       << SpellingLoc.printTreeToString(SM, PrintCode, IndentStr + "  ");
+  }
+  return OS.str();
+}
+
 std::string SourceLocation::printToString(const SourceManager &SM) const {
   std::string S;
   llvm::raw_string_ostream OS(S);
-------------- next part --------------
A non-text attachment was scrubbed...
Name: D768.4.patch
Type: text/x-patch
Size: 3555 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/cfe-commits/attachments/20130523/4ba94e9b/attachment.bin>


More information about the cfe-commits mailing list