diff options
author | Chris Lattner <sabre@nondot.org> | 2007-08-30 06:17:34 +0000 |
---|---|---|
committer | Chris Lattner <sabre@nondot.org> | 2007-08-30 06:17:34 +0000 |
commit | e300c870f08d08badf2ebcb53ded49f304af37fc (patch) | |
tree | db58bec0d43e6e921b67234bba0ec0bdc0b5e2f8 | |
parent | 915311cc10912f15d4e3e7520c3dd8500c33acfc (diff) |
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
-rw-r--r-- | AST/StmtDumper.cpp | 70 | ||||
-rw-r--r-- | clang.xcodeproj/project.pbxproj | 2 | ||||
-rw-r--r-- | include/clang/AST/Stmt.h | 4 |
3 files changed, 67 insertions, 9 deletions
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 <cstdio> using namespace clang; @@ -26,7 +27,7 @@ using namespace clang; namespace { class VISIBILITY_HIDDEN StmtDumper : public StmtVisitor<StmtDumper> { - 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); @@ -122,6 +136,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, ">"); + + // <t2.c:123:421[blah], t2.c:412:321> + +} + + +//===----------------------------------------------------------------------===// // 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<Stmt*>(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<Stmt*>(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 = "<group>"; }; 84D9A8870C1A57E100AC7ABC /* AttributeList.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; name = AttributeList.cpp; path = Parse/AttributeList.cpp; sourceTree = "<group>"; }; 84D9A88B0C1A581300AC7ABC /* AttributeList.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = AttributeList.h; path = clang/Parse/AttributeList.h; sourceTree = "<group>"; }; - 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 = "<group>"; }; DE06756B0C051CFE00EBBFD8 /* ParseExprCXX.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; name = ParseExprCXX.cpp; path = Parse/ParseExprCXX.cpp; sourceTree = "<group>"; }; DE06B73D0A8307640050E87E /* LangOptions.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = LangOptions.h; sourceTree = "<group>"; }; 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. |