Teach the stmtdumper to dump location/range info when a SourceMgr is available.
For example, -parse-ast-dump now prints:
static inline int __inline_isinff(float __x)
(CompoundStmt 0x2409a20
(ReturnStmt 0x2409a10
(BinaryOperator 0x24099f0 'int' <///usr/include/architecture/i386/math.h:183:63, col:102> '=='
(CallExpr 0x24098f0 'float' <col:63, col:82>
(ImplicitCastExpr 0x24098e0 'float (*)(float)' <col:63>
(DeclRefExpr 0x2409880 'float (float)' <col:63> Decl='__builtin_fabsf' 0x2409840))
(DeclRefExpr 0x24098a0 'float' <col:79> Decl='__x' 0x2409810))
(CallExpr 0x24099c0 'float' <col:87, col:102>
(ImplicitCastExpr 0x2409870 'float (*)(void)' <col:87>
(DeclRefExpr 0x2409980 'float (void)' <col:87> Decl='__builtin_inff' 0x2409940))))))
where it only prints filename/line# if it changes from the previous value. We
really need loc info on stmts though, like we have on exprs.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@41602 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/AST/StmtDumper.cpp b/AST/StmtDumper.cpp
index 8e6a712..73aef84 100644
--- a/AST/StmtDumper.cpp
+++ b/AST/StmtDumper.cpp
@@ -16,6 +16,7 @@
#include "clang/AST/Decl.h"
#include "clang/AST/ExprCXX.h"
#include "clang/Lex/IdentifierTable.h"
+#include "clang/Basic/SourceManager.h"
#include "llvm/Support/Compiler.h"
#include <cstdio>
using namespace clang;
@@ -26,7 +27,7 @@
namespace {
class VISIBILITY_HIDDEN StmtDumper : public StmtVisitor<StmtDumper> {
- const SourceManager *SM;
+ SourceManager *SM;
FILE *F;
unsigned IndentLevel;
@@ -34,9 +35,17 @@
/// the first few levels of an AST. This keeps track of how many ast levels
/// are left.
unsigned MaxDepth;
+
+ /// LastLocFilename/LastLocLine - Keep track of the last location we print
+ /// out so that we can print out deltas from then on out.
+ const char *LastLocFilename;
+ unsigned LastLocLine;
public:
- StmtDumper(const SourceManager *sm, FILE *f, unsigned maxDepth)
- : SM(sm), F(f), IndentLevel(0-1), MaxDepth(maxDepth) {}
+ StmtDumper(SourceManager *sm, FILE *f, unsigned maxDepth)
+ : SM(sm), F(f), IndentLevel(0-1), MaxDepth(maxDepth) {
+ LastLocFilename = "";
+ LastLocLine = ~0U;
+ }
void DumpSubTree(Stmt *S) {
// Prune the recursion if not using dump all.
@@ -83,12 +92,17 @@
fprintf(F, "(%s %p", Node->getStmtClassName(), (void*)Node);
}
- void DumpExpr(Expr *Node) const {
+ void DumpExpr(Expr *Node) {
DumpStmt(Node);
fprintf(F, " ");
DumpType(Node->getType());
+ DumpSourceRange(Node);
}
+ void DumpSourceRange(Expr *Node);
+ void DumpLocation(SourceLocation Loc);
+
+
// Stmts.
void VisitStmt(Stmt *Node);
void VisitDeclStmt(DeclStmt *Node);
@@ -122,6 +136,50 @@
}
//===----------------------------------------------------------------------===//
+// Utilities
+//===----------------------------------------------------------------------===//
+
+void StmtDumper::DumpLocation(SourceLocation Loc) {
+ SourceLocation PhysLoc = SM->getPhysicalLoc(Loc);
+
+ // The general format we print out is filename:line:col, but we drop pieces
+ // that haven't changed since the last loc printed.
+ const char *Filename = SM->getSourceName(PhysLoc);
+ unsigned LineNo = SM->getLineNumber(PhysLoc);
+ if (strcmp(Filename, LastLocFilename) != 0) {
+ fprintf(stderr, "%s:%u:%u", Filename, LineNo, SM->getColumnNumber(PhysLoc));
+ LastLocFilename = Filename;
+ LastLocLine = LineNo;
+ } else if (LineNo != LastLocLine) {
+ fprintf(stderr, "line:%u:%u", LineNo, SM->getColumnNumber(PhysLoc));
+ LastLocLine = LineNo;
+ } else {
+ fprintf(stderr, "col:%u", SM->getColumnNumber(PhysLoc));
+ }
+}
+
+void StmtDumper::DumpSourceRange(Expr *Node) {
+ // Can't translate locations if a SourceManager isn't available.
+ if (SM == 0) return;
+
+ // TODO: If the parent expression is available, we can print a delta vs its
+ // location.
+ SourceRange R = Node->getSourceRange();
+
+ fprintf(stderr, " <");
+ DumpLocation(R.Begin());
+ if (R.Begin() != R.End()) {
+ fprintf(stderr, ", ");
+ DumpLocation(R.End());
+ }
+ fprintf(stderr, ">");
+
+ // <t2.c:123:421[blah], t2.c:412:321>
+
+}
+
+
+//===----------------------------------------------------------------------===//
// Stmt printing methods.
//===----------------------------------------------------------------------===//
@@ -342,7 +400,7 @@
/// dump - This does a local dump of the specified AST fragment. It dumps the
/// specified node and a few nodes underneath it, but not the whole subtree.
/// This is useful in a debugger.
-void Stmt::dump(const SourceManager &SM) const {
+void Stmt::dump(SourceManager &SM) const {
StmtDumper P(&SM, stderr, 4);
P.DumpSubTree(const_cast<Stmt*>(this));
fprintf(stderr, "\n");
@@ -358,7 +416,7 @@
}
/// dumpAll - This does a dump of the specified AST fragment and all subtrees.
-void Stmt::dumpAll(const SourceManager &SM) const {
+void Stmt::dumpAll(SourceManager &SM) const {
StmtDumper P(&SM, stderr, ~0U);
P.DumpSubTree(const_cast<Stmt*>(this));
fprintf(stderr, "\n");