[cfe-commits] r64232 - in /cfe/trunk: Driver/ASTConsumers.cpp include/clang/AST/Stmt.h lib/AST/StmtPrinter.cpp

Mike Stump mrs at apple.com
Tue Feb 10 12:16:46 PST 2009


Author: mrs
Date: Tue Feb 10 14:16:46 2009
New Revision: 64232

URL: http://llvm.org/viewvc/llvm-project?rev=64232&view=rev
Log:
Fixup -ast-print so that:

  We handle indentation of decls better.
  We Indent extern "C" { } stuff better.
  We print out structure contents more often.
  We handle pass indentation information into the statement printer, so that
  nested things come out more indented.
  We print out FieldDecls.
  We print out Vars.
  We print out namespaces.
  We indent functions better.

Modified:
    cfe/trunk/Driver/ASTConsumers.cpp
    cfe/trunk/include/clang/AST/Stmt.h
    cfe/trunk/lib/AST/StmtPrinter.cpp

Modified: cfe/trunk/Driver/ASTConsumers.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/Driver/ASTConsumers.cpp?rev=64232&r1=64231&r2=64232&view=diff

==============================================================================
--- cfe/trunk/Driver/ASTConsumers.cpp (original)
+++ cfe/trunk/Driver/ASTConsumers.cpp Tue Feb 10 14:16:46 2009
@@ -34,12 +34,26 @@
   class DeclPrinter {
   public:
     llvm::raw_ostream& Out;
+    unsigned Indentation;
 
-    DeclPrinter(llvm::raw_ostream* out) : Out(out ? *out : llvm::errs()) {}
-    DeclPrinter() : Out(llvm::errs()) {}
+    DeclPrinter(llvm::raw_ostream* out) : Out(out ? *out : llvm::errs()),
+                                          Indentation(0) {}
+    DeclPrinter() : Out(llvm::errs()), Indentation(0) {}
     virtual ~DeclPrinter();
     
+    void ChangeIndent(int I) {
+      Indentation += I;
+    }
+    
+    llvm::raw_ostream& Indent() {
+      for (unsigned i = 0; i < Indentation; ++i)
+        Out << "  ";
+      return Out;
+    }
+
     void PrintDecl(Decl *D);
+    void Print(NamedDecl *ND);
+    void Print(NamespaceDecl *NS);
     void PrintFunctionDeclStart(FunctionDecl *FD);    
     void PrintTypeDefDecl(TypedefDecl *TD);    
     void PrintLinkageSpec(LinkageSpecDecl *LS);
@@ -62,12 +76,13 @@
 }
 
 void DeclPrinter:: PrintDecl(Decl *D) {
+  Indent();
   if (FunctionDecl *FD = dyn_cast<FunctionDecl>(D)) {
     PrintFunctionDeclStart(FD);
 
     if (FD->getBody()) {
       Out << ' ';
-      FD->getBody()->printPretty(Out);
+      FD->getBody()->printPretty(Out, 0, Indentation, true);
       Out << '\n';
     }
   } else if (isa<ObjCMethodDecl>(D)) {
@@ -117,7 +132,23 @@
       Out << "  " << (*E)->getNameAsString() << ",\n";
     Out << "};\n";
   } else if (TagDecl *TD = dyn_cast<TagDecl>(D)) {
-    Out << "Read top-level tag decl: '" << TD->getNameAsString() << "'\n";
+    // print a free standing tag decl (e.g. "struct x;"). 
+    Out << TD->getKindName();
+    Out << " ";
+    if (const IdentifierInfo *II = TD->getIdentifier())
+      Out << II->getName();
+
+    Out << " {\n";
+    ChangeIndent(1);
+    for (DeclContext::decl_iterator i = TD->decls_begin();
+         i != TD->decls_end();
+         ++i)
+      PrintDecl(*i);    
+    ChangeIndent(-1);
+    Indent();
+    Out << "}";
+
+    Out << "\n";
   } else if (TemplateDecl *TempD = dyn_cast<TemplateDecl>(D)) {
     PrintTemplateDecl(TempD);
   } else if (LinkageSpecDecl *LSD = dyn_cast<LinkageSpecDecl>(D)) {
@@ -127,17 +158,61 @@
     AD->getAsmString()->printPretty(Out);
     Out << ")\n";
   } else if (NamedDecl *ND = dyn_cast<NamedDecl>(D)) {
-    Out << "Read top-level variable decl: '" << ND->getNameAsString() << "'\n";
+    Print(ND);
   } else {
     assert(0 && "Unknown decl type!");
   }
 }
 
+void DeclPrinter::Print(NamedDecl *ND) {
+  switch (ND->getKind()) {
+  default:
+    // FIXME: Handle the rest of the NamedDecls.
+    Out << "### NamedDecl " << ND->getNameAsString() << "\n";
+    break;
+  case Decl::Field:
+  case Decl::Var: {
+    // Emit storage class for vardecls.
+    if (VarDecl *V = dyn_cast<VarDecl>(ND)) {
+      switch (V->getStorageClass()) {
+      default: assert(0 && "Unknown storage class!");
+      case VarDecl::None:     break;
+      case VarDecl::Extern:   Out << "extern "; break;
+      case VarDecl::Static:   Out << "static "; break; 
+      case VarDecl::Auto:     Out << "auto "; break;
+      case VarDecl::Register: Out << "register "; break;
+      }
+    }
+    std::string Name = ND->getNameAsString();
+    // This forms: "int a".
+    dyn_cast<ValueDecl>(ND)->getType().getAsStringInternal(Name);
+    Out << Name << ";\n";
+    break;
+  }
+  case Decl::Namespace:
+    Print(dyn_cast<NamespaceDecl>(ND));
+    break;
+  }
+}
+
+void DeclPrinter::Print(NamespaceDecl *NS) {
+  Out << "namespace " << NS->getNameAsString() << " {\n";
+  ChangeIndent(1);
+  for (DeclContext::decl_iterator i = NS->decls_begin();
+       i != NS->decls_end();
+       ++i)
+    PrintDecl(*i);    
+  ChangeIndent(-1);
+  Indent();
+  Out << "}\n";
+}
+
 void DeclPrinter::PrintFunctionDeclStart(FunctionDecl *FD) {
   bool HasBody = FD->getBody();
   
   Out << '\n';
 
+  Indent();
   switch (FD->getStorageClass()) {
   default: assert(0 && "Unknown storage class");
   case FunctionDecl::None: break;
@@ -198,16 +273,20 @@
   }
 
   Out << "extern \"" << l << "\" ";
-  if (LS->hasBraces()) 
+  if (LS->hasBraces()) {
     Out << "{\n";
+    ChangeIndent(1);
+  }
 
   for (LinkageSpecDecl::decl_iterator D = LS->decls_begin(), 
                                    DEnd = LS->decls_end();
        D != DEnd; ++D)
     PrintDecl(*D);
 
-  if (LS->hasBraces())
-    Out << "}";
+  if (LS->hasBraces()) {
+    ChangeIndent(-1);
+    Indent() << "}";
+  }
   Out << "\n";
 }
 
@@ -774,7 +853,7 @@
   for (DeclContext::decl_iterator I = DC->decls_begin(), E = DC->decls_end();
        I != E; ++I) {
     for (unsigned i = 0; i < Indentation; ++i)
-      Out << " ";
+      Out << "  ";
 
     Decl::Kind DK = I->getKind();
     switch (DK) {
@@ -797,7 +876,7 @@
     case Decl::CXXConversion:
     {
       DeclContext* DC = Decl::castToDeclContext(*I);
-      PrintDeclContext(DC, Indentation+4);
+      PrintDeclContext(DC, Indentation+2);
       break;
     }
     case Decl::Field: {

Modified: cfe/trunk/include/clang/AST/Stmt.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/AST/Stmt.h?rev=64232&r1=64231&r2=64232&view=diff

==============================================================================
--- cfe/trunk/include/clang/AST/Stmt.h (original)
+++ cfe/trunk/include/clang/AST/Stmt.h Tue Feb 10 14:16:46 2009
@@ -176,7 +176,8 @@
   /// dumpPretty/printPretty - These two methods do a "pretty print" of the AST
   /// back to its original source language syntax.
   void dumpPretty() const;
-  void printPretty(llvm::raw_ostream &OS, PrinterHelper* = NULL) const;
+  void printPretty(llvm::raw_ostream &OS, PrinterHelper* = NULL, unsigned = 0,
+                   bool NoIndent=false) const;
   
   /// viewAST - Visualize an AST rooted at this Stmt* using GraphViz.  Only
   ///   works on systems with GraphViz (Mac OS X) or dot+gv installed.

Modified: cfe/trunk/lib/AST/StmtPrinter.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/StmtPrinter.cpp?rev=64232&r1=64231&r2=64232&view=diff

==============================================================================
--- cfe/trunk/lib/AST/StmtPrinter.cpp (original)
+++ cfe/trunk/lib/AST/StmtPrinter.cpp Tue Feb 10 14:16:46 2009
@@ -29,10 +29,12 @@
   class VISIBILITY_HIDDEN StmtPrinter : public StmtVisitor<StmtPrinter> {
     llvm::raw_ostream &OS;
     unsigned IndentLevel;
+    bool NoIndent;
     clang::PrinterHelper* Helper;
   public:
-    StmtPrinter(llvm::raw_ostream &os, PrinterHelper* helper) : 
-      OS(os), IndentLevel(0), Helper(helper) {}
+    StmtPrinter(llvm::raw_ostream &os, PrinterHelper* helper, unsigned I=0,
+                bool noIndent=false) :
+      OS(os), IndentLevel(I), NoIndent(noIndent), Helper(helper) {}
     
     void PrintStmt(Stmt *S, int SubIndent = 1) {
       IndentLevel += SubIndent;
@@ -52,6 +54,7 @@
     void PrintRawCompoundStmt(CompoundStmt *S);
     void PrintRawDecl(Decl *D);
     void PrintRawDeclStmt(DeclStmt *S);
+    void PrintFieldDecl(FieldDecl *FD);
     void PrintRawIfStmt(IfStmt *If);
     void PrintRawCXXCatchStmt(CXXCatchStmt *Catch);
     
@@ -62,9 +65,11 @@
         OS << "<null expr>";
     }
     
-    llvm::raw_ostream &Indent(int Delta = 0) const {
-      for (int i = 0, e = IndentLevel+Delta; i < e; ++i)
-        OS << "  ";
+    llvm::raw_ostream &Indent(int Delta = 0) {
+      if (!NoIndent) {
+        for (int i = 0, e = IndentLevel+Delta; i < e; ++i)
+          OS << "  ";
+      } else NoIndent = false;
       return OS;
     }
     
@@ -139,16 +144,25 @@
     OS << " ";
     if (const IdentifierInfo *II = TD->getIdentifier())
       OS << II->getName();
-    else
-      OS << "<anonymous>";
-    // FIXME: print tag bodies.
+    if (RecordDecl *RD = dyn_cast<RecordDecl>(TD)) {
+      OS << "{\n";
+      IndentLevel += 1;
+      for (RecordDecl::field_iterator i = RD->field_begin(); i != RD->field_end(); ++i) {
+        PrintFieldDecl(*i);
+      IndentLevel -= 1;
+      }
+    }
   } else {
     assert(0 && "Unexpected decl");
   }
 }
 
+void StmtPrinter::PrintFieldDecl(FieldDecl *FD) {
+  Indent() << FD->getNameAsString() << "\n";
+}
+
 void StmtPrinter::PrintRawDeclStmt(DeclStmt *S) {
-  bool isFirst = false;
+  bool isFirst = true;
   
   for (DeclStmt::decl_iterator I = S->decl_begin(), E = S->decl_end();
        I != E; ++I) {
@@ -1222,13 +1236,14 @@
   OS.flush();
 }
 
-void Stmt::printPretty(llvm::raw_ostream &OS, PrinterHelper* Helper) const {
+void Stmt::printPretty(llvm::raw_ostream &OS, PrinterHelper* Helper,
+                       unsigned I, bool NoIndent) const {
   if (this == 0) {
     OS << "<NULL>";
     return;
   }
 
-  StmtPrinter P(OS, Helper);
+  StmtPrinter P(OS, Helper, I, NoIndent);
   P.Visit(const_cast<Stmt*>(this));
 }
 





More information about the cfe-commits mailing list