From: Chris Lattner Date: Thu, 30 Aug 2007 06:17:34 +0000 (+0000) Subject: Teach the stmtdumper to dump location/range info when a SourceMgr is available. X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=e300c870f08d08badf2ebcb53ded49f304af37fc;p=clang 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' '==' (CallExpr 0x24098f0 'float' (ImplicitCastExpr 0x24098e0 'float (*)(float)' (DeclRefExpr 0x2409880 'float (float)' Decl='__builtin_fabsf' 0x2409840)) (DeclRefExpr 0x24098a0 'float' Decl='__x' 0x2409810)) (CallExpr 0x24099c0 'float' (ImplicitCastExpr 0x2409870 'float (*)(void)' (DeclRefExpr 0x2409980 'float (void)' 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 8e6a7128de..73aef84742 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 using namespace clang; @@ -26,7 +27,7 @@ using namespace clang; namespace { class VISIBILITY_HIDDEN StmtDumper : public StmtVisitor { - const SourceManager *SM; + SourceManager *SM; FILE *F; unsigned IndentLevel; @@ -34,9 +35,17 @@ namespace { /// 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 @@ namespace { 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); @@ -121,6 +135,50 @@ namespace { }; } +//===----------------------------------------------------------------------===// +// 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, ">"); + + // + +} + + //===----------------------------------------------------------------------===// // Stmt printing methods. //===----------------------------------------------------------------------===// @@ -342,7 +400,7 @@ void StmtDumper::VisitObjCEncodeExpr(ObjCEncodeExpr *Node) { /// 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(this)); fprintf(stderr, "\n"); @@ -358,7 +416,7 @@ void Stmt::dump() const { } /// 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(this)); fprintf(stderr, "\n"); diff --git a/clang.xcodeproj/project.pbxproj b/clang.xcodeproj/project.pbxproj index d86dfbb0ee..cb6a73d08b 100644 --- a/clang.xcodeproj/project.pbxproj +++ b/clang.xcodeproj/project.pbxproj @@ -210,7 +210,7 @@ 35260CA40C7F75C000D66CE9 /* ExprCXX.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = ExprCXX.cpp; path = AST/ExprCXX.cpp; sourceTree = ""; }; 84D9A8870C1A57E100AC7ABC /* AttributeList.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; name = AttributeList.cpp; path = Parse/AttributeList.cpp; sourceTree = ""; }; 84D9A88B0C1A581300AC7ABC /* AttributeList.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = AttributeList.h; path = clang/Parse/AttributeList.h; sourceTree = ""; }; - 8DD76F6C0486A84900D96B5E /* clang */ = {isa = PBXFileReference; includeInIndex = 0; lastKnownFileType = "compiled.mach-o.executable"; path = clang; sourceTree = BUILT_PRODUCTS_DIR; }; + 8DD76F6C0486A84900D96B5E /* clang */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = clang; sourceTree = BUILT_PRODUCTS_DIR; }; DE01DA480B12ADA300AC22CE /* PPCallbacks.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = PPCallbacks.h; sourceTree = ""; }; DE06756B0C051CFE00EBBFD8 /* ParseExprCXX.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; name = ParseExprCXX.cpp; path = Parse/ParseExprCXX.cpp; sourceTree = ""; }; DE06B73D0A8307640050E87E /* LangOptions.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = LangOptions.h; sourceTree = ""; }; diff --git a/include/clang/AST/Stmt.h b/include/clang/AST/Stmt.h index 8241bf65ac..6b0d58767c 100644 --- a/include/clang/AST/Stmt.h +++ b/include/clang/AST/Stmt.h @@ -58,11 +58,11 @@ public: /// specified node and a few nodes underneath it, but not the whole subtree. /// This is useful in a debugger. void dump() const; - void dump(const SourceManager &SM) const; + void dump(SourceManager &SM) const; /// dumpAll - This does a dump of the specified AST fragment and all subtrees. void dumpAll() const; - void dumpAll(const SourceManager &SM) const; + void dumpAll(SourceManager &SM) const; /// dumpPretty/printPretty - These two methods do a "pretty print" of the AST /// back to its original source language syntax.