[cfe-commits] r167509 - in /cfe/trunk: lib/AST/StmtDumper.cpp test/Misc/ast-dump-stmt.c test/Misc/ast-dump-stmt.m

Manuel Klimek klimek at google.com
Tue Nov 6 16:33:12 PST 2012


Author: klimek
Date: Tue Nov  6 18:33:12 2012
New Revision: 167509

URL: http://llvm.org/viewvc/llvm-project?rev=167509&view=rev
Log:
Create helper functions in StmtDumper for outputting the indentation, newlines, and brackets.

This is preparation for adding Decl dumping.

Patch by Philip Craig.

Added:
    cfe/trunk/test/Misc/ast-dump-stmt.c
    cfe/trunk/test/Misc/ast-dump-stmt.m
Modified:
    cfe/trunk/lib/AST/StmtDumper.cpp

Modified: cfe/trunk/lib/AST/StmtDumper.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/StmtDumper.cpp?rev=167509&r1=167508&r2=167509&view=diff
==============================================================================
--- cfe/trunk/lib/AST/StmtDumper.cpp (original)
+++ cfe/trunk/lib/AST/StmtDumper.cpp Tue Nov  6 18:33:12 2012
@@ -7,7 +7,7 @@
 //
 //===----------------------------------------------------------------------===//
 //
-// This file implements the Stmt::dump/Stmt::print methods, which dump out the
+// This file implements the Stmt::dump method, which dumps out the
 // AST in a form that exposes type details and other fields.
 //
 //===----------------------------------------------------------------------===//
@@ -30,6 +30,7 @@
     SourceManager *SM;
     raw_ostream &OS;
     unsigned IndentLevel;
+    bool IsFirstLine;
 
     /// MaxDepth - When doing a normal dump (not dumpAll) we only want to dump
     /// the first few levels of an AST.  This keeps track of how many ast levels
@@ -41,46 +42,64 @@
     const char *LastLocFilename;
     unsigned LastLocLine;
 
+    class IndentScope {
+      StmtDumper &Dumper;
+    public:
+      IndentScope(StmtDumper &Dumper) : Dumper(Dumper) {
+        Dumper.indent();
+      }
+      ~IndentScope() {
+        Dumper.unindent();
+      }
+    };
+
   public:
     StmtDumper(SourceManager *sm, raw_ostream &os, unsigned maxDepth)
-      : SM(sm), OS(os), IndentLevel(0-1), MaxDepth(maxDepth) {
+      : SM(sm), OS(os), IndentLevel(0), IsFirstLine(true), MaxDepth(maxDepth) {
       LastLocFilename = "";
       LastLocLine = ~0U;
     }
 
+    ~StmtDumper() {
+      OS << "\n";
+    }
+
     void DumpSubTree(Stmt *S) {
       // Prune the recursion if not using dump all.
       if (MaxDepth == 0) return;
 
-      ++IndentLevel;
-      if (S) {
-        if (DeclStmt* DS = dyn_cast<DeclStmt>(S))
-          VisitDeclStmt(DS);
-        else {
-          Visit(S);
-
-          // Print out children.
-          Stmt::child_range CI = S->children();
-          if (CI) {
-            while (CI) {
-              OS << '\n';
-              DumpSubTree(*CI++);
-            }
-          }
-        }
-        OS << ')';
-      } else {
-        Indent();
+      IndentScope Indent(*this);
+
+      if (!S) {
         OS << "<<<NULL>>>";
+        return;
+      }
+
+      if (DeclStmt* DS = dyn_cast<DeclStmt>(S)) {
+        VisitDeclStmt(DS);
+        return;
       }
-      --IndentLevel;
+
+      Visit(S);
+      for (Stmt::child_range CI = S->children(); CI; CI++)
+        DumpSubTree(*CI);
     }
 
     void DumpDeclarator(Decl *D);
 
-    void Indent() const {
-      for (int i = 0, e = IndentLevel; i < e; ++i)
-        OS << "  ";
+    void indent() {
+      if (IsFirstLine)
+        IsFirstLine = false;
+      else
+        OS << "\n";
+      OS.indent(IndentLevel * 2);
+      OS << "(";
+      IndentLevel++;
+    }
+
+    void unindent() {
+      OS << ")";
+      IndentLevel--;
     }
 
     void DumpType(QualType T) {
@@ -96,8 +115,7 @@
     }
     void DumpDeclRef(Decl *node);
     void DumpStmt(const Stmt *Node) {
-      Indent();
-      OS << "(" << Node->getStmtClassName()
+      OS << Node->getStmtClassName()
          << " " << (const void*)Node;
       DumpSourceRange(Node);
     }
@@ -262,7 +280,7 @@
     // If this is a vardecl with an initializer, emit it.
     if (VarDecl *V = dyn_cast<VarDecl>(VD)) {
       if (V->getInit()) {
-        OS << " =\n";
+        OS << " =";
         DumpSubTree(V->getInit());
       }
     }
@@ -294,9 +312,9 @@
   } else if (LabelDecl *LD = dyn_cast<LabelDecl>(D)) {
     OS << "label " << *LD;
   } else if (StaticAssertDecl *SAD = dyn_cast<StaticAssertDecl>(D)) {
-    OS << "\"static_assert(\n";
+    OS << "\"static_assert(";
     DumpSubTree(SAD->getAssertExpr());
-    OS << ",\n";
+    OS << ",";
     DumpSubTree(SAD->getMessage());
     OS << ");\"";
   } else {
@@ -306,17 +324,12 @@
 
 void StmtDumper::VisitDeclStmt(DeclStmt *Node) {
   DumpStmt(Node);
-  OS << "\n";
   for (DeclStmt::decl_iterator DI = Node->decl_begin(), DE = Node->decl_end();
        DI != DE; ++DI) {
+    IndentScope Indent(*this);
     Decl* D = *DI;
-    ++IndentLevel;
-    Indent();
     OS << (void*) D << " ";
     DumpDeclarator(D);
-    if (DI+1 != DE)
-      OS << "\n";
-    --IndentLevel;
   }
 }
 
@@ -503,35 +516,29 @@
   BlockDecl *block = Node->getBlockDecl();
   OS << " decl=" << block;
 
-  IndentLevel++;
   if (block->capturesCXXThis()) {
-    OS << '\n'; Indent(); OS << "(capture this)";
+    IndentScope Indent(*this);
+    OS << "capture this";
   }
   for (BlockDecl::capture_iterator
          i = block->capture_begin(), e = block->capture_end(); i != e; ++i) {
-    OS << '\n';
-    Indent();
-    OS << "(capture ";
+    IndentScope Indent(*this);
+    OS << "capture ";
     if (i->isByRef()) OS << "byref ";
     if (i->isNested()) OS << "nested ";
     if (i->getVariable())
       DumpDeclRef(i->getVariable());
     if (i->hasCopyExpr()) DumpSubTree(i->getCopyExpr());
-    OS << ")";
   }
-  IndentLevel--;
 
-  OS << '\n';
   DumpSubTree(block->getBody());
 }
 
 void StmtDumper::VisitOpaqueValueExpr(OpaqueValueExpr *Node) {
   DumpExpr(Node);
 
-  if (Expr *Source = Node->getSourceExpr()) {
-    OS << '\n';
+  if (Expr *Source = Node->getSourceExpr())
     DumpSubTree(Source);
-  }
 }
 
 // GNU extensions.
@@ -589,15 +596,11 @@
 
 void StmtDumper::VisitExprWithCleanups(ExprWithCleanups *Node) {
   DumpExpr(Node);
-  ++IndentLevel;
   for (unsigned i = 0, e = Node->getNumObjects(); i != e; ++i) {
-    OS << "\n";
-    Indent();
-    OS << "(cleanup ";
+    IndentScope Indent(*this);
+    OS << "cleanup ";
     DumpDeclRef(Node->getObject(i));
-    OS << ")";
   }
-  --IndentLevel;
 }
 
 void StmtDumper::DumpCXXTemporary(CXXTemporary *Temporary) {
@@ -734,7 +737,6 @@
 void Stmt::dump(raw_ostream &OS, SourceManager &SM) const {
   StmtDumper P(&SM, OS, 4);
   P.DumpSubTree(const_cast<Stmt*>(this));
-  OS << "\n";
 }
 
 /// dump - This does a local dump of the specified AST fragment.  It dumps the
@@ -743,19 +745,16 @@
 void Stmt::dump() const {
   StmtDumper P(0, llvm::errs(), 4);
   P.DumpSubTree(const_cast<Stmt*>(this));
-  llvm::errs() << "\n";
 }
 
 /// dumpAll - This does a dump of the specified AST fragment and all subtrees.
 void Stmt::dumpAll(SourceManager &SM) const {
   StmtDumper P(&SM, llvm::errs(), ~0U);
   P.DumpSubTree(const_cast<Stmt*>(this));
-  llvm::errs() << "\n";
 }
 
 /// dumpAll - This does a dump of the specified AST fragment and all subtrees.
 void Stmt::dumpAll() const {
   StmtDumper P(0, llvm::errs(), ~0U);
   P.DumpSubTree(const_cast<Stmt*>(this));
-  llvm::errs() << "\n";
 }

Added: cfe/trunk/test/Misc/ast-dump-stmt.c
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Misc/ast-dump-stmt.c?rev=167509&view=auto
==============================================================================
--- cfe/trunk/test/Misc/ast-dump-stmt.c (added)
+++ cfe/trunk/test/Misc/ast-dump-stmt.c Tue Nov  6 18:33:12 2012
@@ -0,0 +1,35 @@
+// RUN: %clang_cc1 -ast-dump -ast-dump-filter Test %s | FileCheck -strict-whitespace %s
+
+int TestLocation = 0;
+// CHECK:      Dumping TestLocation
+// CHECK-NEXT:   IntegerLiteral 0x{{[^ ]*}} <{{.*}}:3:20> 'int' 0
+
+int TestIndent = 1 + (1);
+// CHECK:      Dumping TestIndent
+// CHECK-NEXT: {{\(BinaryOperator[^()]*$}}
+// CHECK-NEXT: {{^  \(IntegerLiteral.*0[^()]*\)$}}
+// CHECK-NEXT: {{^  \(ParenExpr.*0[^()]*$}}
+// CHECK-NEXT: {{^    \(IntegerLiteral.*0[^()]*\)\)\)$}}
+
+void TestDeclStmt() {
+  int x = 0;
+  int y, z;
+}
+// CHECK:      Dumping TestDeclStmt
+// CHECK-NEXT: CompoundStmt
+// CHECK-NEXT:   DeclStmt
+// CHECK-NEXT:     int x =
+// CHECK-NEXT:       IntegerLiteral
+// CHECK-NEXT:   DeclStmt
+// CHECK-NEXT:     int y
+// CHECK-NEXT:     int z
+
+int TestOpaqueValueExpr = 0 ?: 1;
+// CHECK:      Dumping TestOpaqueValueExpr
+// CHECK-NEXT: BinaryConditionalOperator
+// CHECK-NEXT:   IntegerLiteral
+// CHECK-NEXT:   OpaqueValueExpr
+// CHECK-NEXT:     IntegerLiteral
+// CHECK-NEXT:   OpaqueValueExpr
+// CHECK-NEXT:     IntegerLiteral
+// CHECK-NEXT:   IntegerLiteral

Added: cfe/trunk/test/Misc/ast-dump-stmt.m
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Misc/ast-dump-stmt.m?rev=167509&view=auto
==============================================================================
--- cfe/trunk/test/Misc/ast-dump-stmt.m (added)
+++ cfe/trunk/test/Misc/ast-dump-stmt.m Tue Nov  6 18:33:12 2012
@@ -0,0 +1,36 @@
+// RUN: %clang_cc1 -Wno-unused -fblocks -fobjc-exceptions -ast-dump -ast-dump-filter Test %s | FileCheck -strict-whitespace %s
+
+void TestBlockExpr(int x) {
+  ^{ x; };
+}
+// CHECK:      Dumping TestBlockExpr
+// CHECK:      BlockExpr{{.*}} decl=
+// CHECK-NEXT:   capture ParmVar
+// CHECK-NEXT:   CompoundStmt
+
+void TestExprWithCleanup(int x) {
+  ^{ x; };
+}
+// CHECK:      Dumping TestExprWithCleanup
+// CHECK:      ExprWithCleanups
+// CHECK-NEXT:   cleanup Block
+// CHECK-NEXT:   BlockExpr
+
+ at interface A
+ at end
+
+void TestObjCAtCatchStmt() {
+  @try {
+  } @catch(A *a) {
+  } @catch(...) {
+  } @finally {
+  }
+}
+// CHECK:      Dumping TestObjCAtCatchStmt
+// CHECK:      ObjCAtTryStmt
+// CHECK-NEXT:   CompoundStmt
+// CHECK-NEXT:   ObjCAtCatchStmt{{.*}} catch parm = "A *a"
+// CHECK-NEXT:     CompoundStmt
+// CHECK-NEXT:   ObjCAtCatchStmt{{.*}} catch all
+// CHECK-NEXT:     CompoundStmt
+// CHECK-NEXT:   ObjCAtFinallyStmt





More information about the cfe-commits mailing list