diff --git a/lib/Frontend/ASTConsumers.cpp b/lib/Frontend/ASTConsumers.cpp
index c35f4c9..11c9251 100644
--- a/lib/Frontend/ASTConsumers.cpp
+++ b/lib/Frontend/ASTConsumers.cpp
@@ -30,559 +30,21 @@
 using namespace clang;
 
 //===----------------------------------------------------------------------===//
-/// DeclPrinter - Utility class for printing top-level decls.
+/// ASTPrinter - Pretty-printer and dumper of ASTs
 
 namespace {
-  class DeclPrinter {
+  class ASTPrinter : public ASTConsumer {
+    llvm::raw_ostream &Out;
+    bool Dump;
+    
   public:
-    llvm::raw_ostream& Out;
-    PrintingPolicy Policy;
-    unsigned Indentation;
-
-    DeclPrinter(llvm::raw_ostream* out,
-                const PrintingPolicy &Policy = PrintingPolicy()) 
-      : Out(out ? *out : llvm::errs()), Policy(Policy),
-        Indentation(0) {}
-    DeclPrinter() : Out(llvm::errs()), Indentation(0) {}
-    virtual ~DeclPrinter();
+    ASTPrinter(llvm::raw_ostream* o = NULL, bool Dump = false) 
+      : Out(o? *o : llvm::errs()), Dump(Dump) { }
     
-    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);
-    void PrintObjCMethodDecl(ObjCMethodDecl *OMD);    
-    void PrintObjCImplementationDecl(ObjCImplementationDecl *OID);
-    void PrintObjCInterfaceDecl(ObjCInterfaceDecl *OID);
-    void PrintObjCProtocolDecl(ObjCProtocolDecl *PID);  
-    void PrintObjCCategoryImplDecl(ObjCCategoryImplDecl *PID);    
-    void PrintObjCCategoryDecl(ObjCCategoryDecl *PID);    
-    void PrintObjCCompatibleAliasDecl(ObjCCompatibleAliasDecl *AID);
-    void PrintObjCPropertyDecl(ObjCPropertyDecl *PD);
-    void PrintObjCPropertyImplDecl(ObjCPropertyImplDecl *PID);
-
-    void PrintTemplateDecl(TemplateDecl *TD);
-  };
-} // end anonymous namespace
-
-DeclPrinter::~DeclPrinter() {
-  Out.flush();
-}
-
-void DeclPrinter:: PrintDecl(Decl *D) {
-  Indent();
-  if (FunctionDecl *FD = dyn_cast<FunctionDecl>(D)) {
-    PrintFunctionDeclStart(FD);
-
-    // FIXME: Pass a context here so we can use getBody()
-    if (FD->getBodyIfAvailable()) {
-      Out << ' ';
-      FD->getBodyIfAvailable()->printPretty(Out, 0, Policy);
-      Out << '\n';
-    }
-  } else if (isa<ObjCMethodDecl>(D)) {
-    // Do nothing, methods definitions are printed in
-    // PrintObjCImplementationDecl.
-  } else if (TypedefDecl *TD = dyn_cast<TypedefDecl>(D)) {
-    PrintTypeDefDecl(TD);
-  } else if (ObjCInterfaceDecl *OID = dyn_cast<ObjCInterfaceDecl>(D)) {
-    PrintObjCInterfaceDecl(OID);
-  } else if (ObjCProtocolDecl *PID = dyn_cast<ObjCProtocolDecl>(D)) {
-    PrintObjCProtocolDecl(PID);
-  } else if (ObjCForwardProtocolDecl *OFPD = 
-             dyn_cast<ObjCForwardProtocolDecl>(D)) {
-    Out << "@protocol ";
-    for (ObjCForwardProtocolDecl::protocol_iterator I = OFPD->protocol_begin(), 
-                                                    E = OFPD->protocol_end();
-         I != E; ++I) {
-      if (I != OFPD->protocol_begin()) Out << ", ";
-      Out << (*I)->getNameAsString();
-    }
-    Out << ";\n";
-  } else if (ObjCImplementationDecl *OID = 
-             dyn_cast<ObjCImplementationDecl>(D)) {
-    PrintObjCImplementationDecl(OID);
-  } else if (ObjCCategoryImplDecl *OID = 
-             dyn_cast<ObjCCategoryImplDecl>(D)) {
-    PrintObjCCategoryImplDecl(OID);
-  } else if (ObjCCategoryDecl *OID = 
-             dyn_cast<ObjCCategoryDecl>(D)) {
-    PrintObjCCategoryDecl(OID);
-  } else if (ObjCCompatibleAliasDecl *OID = 
-             dyn_cast<ObjCCompatibleAliasDecl>(D)) {
-    PrintObjCCompatibleAliasDecl(OID);
-  } else if (ObjCClassDecl *OFCD = dyn_cast<ObjCClassDecl>(D)) {
-    Out << "@class ";
-    for (ObjCClassDecl::iterator I = OFCD->begin(), E = OFCD->end();
-         I != E; ++I) {
-      if (I != OFCD->begin()) Out << ", ";
-      Out << (*I)->getNameAsString();
-    }
-    Out << ";\n";
-  } else if (EnumDecl *ED = dyn_cast<EnumDecl>(D)) {
-    Out << "enum " << ED->getNameAsString() << " {\n";
-    // FIXME: Shouldn't pass a NULL context
-    ASTContext *Context = 0;
-    for (EnumDecl::enumerator_iterator E = ED->enumerator_begin(*Context),
-                                    EEnd = ED->enumerator_end(*Context);
-         E != EEnd; ++E)
-      Out << "  " << (*E)->getNameAsString() << ",\n";
-    Out << "};\n";
-  } else if (TagDecl *TD = dyn_cast<TagDecl>(D)) {
-    // print a free standing tag decl (e.g. "struct x;"). 
-    Out << TD->getKindName();
-    Out << " ";
-    if (const IdentifierInfo *II = TD->getIdentifier())
-      Out << II->getName();
-
-    if (TD->isDefinition()) {
-      Out << " {\n";
-      ChangeIndent(1);
-      // FIXME: Shouldn't pass a NULL context
-      ASTContext *Context = 0;
-      for (DeclContext::decl_iterator i = TD->decls_begin(*Context);
-           i != TD->decls_end(*Context);
-           ++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)) {
-    PrintLinkageSpec(LSD);
-  } else if (FileScopeAsmDecl *AD = dyn_cast<FileScopeAsmDecl>(D)) {
-    Out << "asm(";
-    AD->getAsmString()->printPretty(Out, 0, Policy);
-    Out << ")\n";
-  } else if (NamedDecl *ND = dyn_cast<NamedDecl>(D)) {
-    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::Auto:          Out << "auto "; break;
-      case VarDecl::Register:      Out << "register "; break;
-      case VarDecl::Extern:        Out << "extern "; break;
-      case VarDecl::Static:        Out << "static "; break; 
-      case VarDecl::PrivateExtern: Out << "__private_extern__ "; break; 
-      }
-    }
-    std::string Name = ND->getNameAsString();
-    // This forms: "int a".
-    dyn_cast<ValueDecl>(ND)->getType().getAsStringInternal(Name, Policy);
-    Out << Name;
-    if (VarDecl *Var = dyn_cast<VarDecl>(ND)) {
-      if (Var->getInit()) {
-        Out << " = ";
-        Var->getInit()->printPretty(Out, 0, Policy);
-      }
-    }
-    Out << ";\n";
-    break;
-  }
-  case Decl::Namespace:
-    Print(dyn_cast<NamespaceDecl>(ND));
-    break;
-  }
-}
-
-void DeclPrinter::Print(NamespaceDecl *NS) {
-  Out << "namespace " << NS->getNameAsString() << " {\n";
-  ChangeIndent(1);
-  // FIXME: Shouldn't pass a NULL context
-  ASTContext *Context = 0;
-  for (DeclContext::decl_iterator i = NS->decls_begin(*Context);
-       i != NS->decls_end(*Context);
-       ++i)
-    PrintDecl(*i);    
-  ChangeIndent(-1);
-  Indent();
-  Out << "}\n";
-}
-
-void DeclPrinter::PrintFunctionDeclStart(FunctionDecl *FD) {
-  // FIXME: pass a context so that we can use getBody.
-  bool HasBody = FD->getBodyIfAvailable();
-  
-  Out << '\n';
-
-  Indent();
-  switch (FD->getStorageClass()) {
-  default: assert(0 && "Unknown storage class");
-  case FunctionDecl::None: break;
-  case FunctionDecl::Extern: Out << "extern "; break;
-  case FunctionDecl::Static: Out << "static "; break;
-  case FunctionDecl::PrivateExtern: Out << "__private_extern__ "; break;
-  }
-  
-  if (FD->isInline())
-    Out << "inline ";
-  
-  std::string Proto = FD->getNameAsString();
-  const FunctionType *AFT = FD->getType()->getAsFunctionType();
-
-  if (const FunctionProtoType *FT = dyn_cast<FunctionProtoType>(AFT)) {
-    Proto += "(";
-    for (unsigned i = 0, e = FD->getNumParams(); i != e; ++i) {
-      if (i) Proto += ", ";
-      std::string ParamStr;
-      if (HasBody) ParamStr = FD->getParamDecl(i)->getNameAsString();
-      
-      FT->getArgType(i).getAsStringInternal(ParamStr, Policy);
-      Proto += ParamStr;
-    }
-    
-    if (FT->isVariadic()) {
-      if (FD->getNumParams()) Proto += ", ";
-      Proto += "...";
-    }
-    Proto += ")";
-  } else {
-    assert(isa<FunctionNoProtoType>(AFT));
-    Proto += "()";
-  }
-
-  AFT->getResultType().getAsStringInternal(Proto, Policy);
-  Out << Proto;
-  
-  if (!FD->getBodyIfAvailable())
-    Out << ";\n";
-  // Doesn't print the body.
-}
-
-void DeclPrinter::PrintTypeDefDecl(TypedefDecl *TD) {
-  std::string S = TD->getNameAsString();
-  TD->getUnderlyingType().getAsStringInternal(S, Policy);
-  Out << "typedef " << S << ";\n";
-}
-
-void DeclPrinter::PrintLinkageSpec(LinkageSpecDecl *LS) {
-  const char *l;
-  if (LS->getLanguage() == LinkageSpecDecl::lang_c)
-    l = "C";
-  else {
-    assert(LS->getLanguage() == LinkageSpecDecl::lang_cxx &&
-           "unknown language in linkage specification");
-    l = "C++";
-  }
-
-  Out << "extern \"" << l << "\" ";
-  if (LS->hasBraces()) {
-    Out << "{\n";
-    ChangeIndent(1);
-  }
-
-  // FIXME: Should not use a NULL DeclContext!
-  ASTContext *Context = 0;
-  for (LinkageSpecDecl::decl_iterator D = LS->decls_begin(*Context), 
-                                   DEnd = LS->decls_end(*Context);
-       D != DEnd; ++D)
-    PrintDecl(*D);
-
-  if (LS->hasBraces()) {
-    ChangeIndent(-1);
-    Indent() << "}";
-  }
-  Out << "\n";
-}
-
-void DeclPrinter::PrintObjCMethodDecl(ObjCMethodDecl *OMD) {
-  if (OMD->isInstanceMethod())
-    Out << "\n- ";
-  else 
-    Out << "\n+ ";
-  if (!OMD->getResultType().isNull())
-    Out << '(' << OMD->getResultType().getAsString() << ")";
-  
-  std::string name = OMD->getSelector().getAsString();
-  std::string::size_type pos, lastPos = 0;
-  for (ObjCMethodDecl::param_iterator PI = OMD->param_begin(),
-       E = OMD->param_end(); PI != E; ++PI) {
-    // FIXME: selector is missing here!    
-    pos = name.find_first_of(":", lastPos);
-    Out << " " << name.substr(lastPos, pos - lastPos);
-    Out << ":(" << (*PI)->getType().getAsString() << ")"
-        << (*PI)->getNameAsString(); 
-    lastPos = pos + 1;
-  }
-    
-  if (OMD->param_begin() == OMD->param_end())
-    Out << " " << name;
-    
-  if (OMD->isVariadic())
-      Out << ", ...";
-  
-  Out << ";";
-}
-
-void DeclPrinter::PrintObjCImplementationDecl(ObjCImplementationDecl *OID) {
-  std::string I = OID->getNameAsString();
-  ObjCInterfaceDecl *SID = OID->getSuperClass();
-
-  if (SID)
-    Out << "@implementation " << I << " : " << SID->getNameAsString();
-  else
-    Out << "@implementation " << I;
-  
-  // FIXME: Don't use a NULL context
-  ASTContext *Context = 0;
-  for (ObjCImplementationDecl::instmeth_iterator 
-         I = OID->instmeth_begin(*Context),
-         E = OID->instmeth_end(*Context); 
-       I != E; ++I) {
-    ObjCMethodDecl *OMD = *I;
-    PrintObjCMethodDecl(OMD);
-    if (OMD->getBody()) {
-      Out << ' ';
-      OMD->getBody()->printPretty(Out, 0, Policy);
-      Out << '\n';
-    }
-  }
-  
-  for (ObjCImplementationDecl::classmeth_iterator 
-         I = OID->classmeth_begin(*Context),
-       E = OID->classmeth_end(*Context);
-       I != E; ++I) {
-    ObjCMethodDecl *OMD = *I;
-    PrintObjCMethodDecl(OMD);
-    if (OMD->getBody()) {
-      Out << ' ';
-      OMD->getBody()->printPretty(Out, 0, Policy);
-      Out << '\n';
-    }
-  }
-  
-  for (ObjCImplementationDecl::propimpl_iterator 
-         I = OID->propimpl_begin(*Context),
-         E = OID->propimpl_end(*Context); I != E; ++I)
-    PrintObjCPropertyImplDecl(*I);
-  
-  Out << "@end\n";
-}
-
-
-void DeclPrinter::PrintObjCInterfaceDecl(ObjCInterfaceDecl *OID) {
-  std::string I = OID->getNameAsString();
-  ObjCInterfaceDecl *SID = OID->getSuperClass();
-
-  if (SID)
-    Out << "@interface " << I << " : " << SID->getNameAsString();
-  else
-    Out << "@interface " << I;
-  
-  // Protocols?
-  const ObjCList<ObjCProtocolDecl> &Protocols = OID->getReferencedProtocols();
-  if (!Protocols.empty()) {
-    for (ObjCList<ObjCProtocolDecl>::iterator I = Protocols.begin(),
-         E = Protocols.end(); I != E; ++I)
-      Out << (I == Protocols.begin() ? '<' : ',') << (*I)->getNameAsString();
-  }
-  
-  if (!Protocols.empty())
-    Out << ">";
-  Out << '\n';
-  
-  if (OID->ivar_size() > 0) {
-    Out << '{';
-    for (ObjCInterfaceDecl::ivar_iterator I = OID->ivar_begin(),
-         E = OID->ivar_end(); I != E; ++I) {
-      Out << '\t' << (*I)->getType().getAsString()
-          << ' '  << (*I)->getNameAsString() << ";\n";      
-    }
-    Out << "}\n";
-  }
-  
-  // FIXME: Should not use a NULL DeclContext!
-  ASTContext *Context = 0;
-  for (ObjCInterfaceDecl::prop_iterator I = OID->prop_begin(*Context),
-       E = OID->prop_end(*Context); I != E; ++I)
-    PrintObjCPropertyDecl(*I);
-  bool eol_needed = false;
-  for (ObjCInterfaceDecl::classmeth_iterator I = OID->classmeth_begin(*Context),
-       E = OID->classmeth_end(*Context); I != E; ++I)
-    eol_needed = true, PrintObjCMethodDecl(*I);
-  
-  for (ObjCInterfaceDecl::instmeth_iterator I = OID->instmeth_begin(*Context),
-       E = OID->instmeth_end(*Context); I != E; ++I)
-    eol_needed = true, PrintObjCMethodDecl(*I);
-  
-  Out << (eol_needed ? "\n@end\n" : "@end\n");
-  // FIXME: implement the rest...
-}
-
-void DeclPrinter::PrintObjCProtocolDecl(ObjCProtocolDecl *PID) {
-  Out << "@protocol " << PID->getNameAsString() << '\n';
-  
-  // FIXME: Should not use a NULL DeclContext!
-  ASTContext *Context = 0;
-  for (ObjCProtocolDecl::prop_iterator I = PID->prop_begin(*Context),
-       E = PID->prop_end(*Context); I != E; ++I)
-    PrintObjCPropertyDecl(*I);
-  Out << "@end\n";
-  // FIXME: implement the rest...
-}
-
-void DeclPrinter::PrintObjCCategoryImplDecl(ObjCCategoryImplDecl *PID) {
-  Out << "@implementation "
-      << PID->getClassInterface()->getNameAsString()
-      << '(' << PID->getNameAsString() << ");\n";  
-
-  // FIXME: Don't use a NULL context here
-  ASTContext *Context = 0;
-  for (ObjCCategoryImplDecl::propimpl_iterator 
-         I = PID->propimpl_begin(*Context),
-       E = PID->propimpl_end(*Context); I != E; ++I)
-    PrintObjCPropertyImplDecl(*I);
-  Out << "@end\n";
-  // FIXME: implement the rest...
-}
-
-void DeclPrinter::PrintObjCCategoryDecl(ObjCCategoryDecl *PID) {
-  // FIXME: Should not use a NULL DeclContext!
-  ASTContext *Context = 0;
-  Out << "@interface " 
-      << PID->getClassInterface()->getNameAsString()
-      << '(' << PID->getNameAsString() << ");\n";
-  // Output property declarations.
-  for (ObjCCategoryDecl::prop_iterator I = PID->prop_begin(*Context),
-       E = PID->prop_end(*Context); I != E; ++I)
-    PrintObjCPropertyDecl(*I);
-  Out << "@end\n";
-  
-  // FIXME: implement the rest...
-}
-
-void DeclPrinter::PrintObjCCompatibleAliasDecl(ObjCCompatibleAliasDecl *AID) {
-  Out << "@compatibility_alias " << AID->getNameAsString() 
-      << ' ' << AID->getClassInterface()->getNameAsString() << ";\n";  
-}
-
-/// PrintObjCPropertyDecl - print a property declaration.
-///
-void DeclPrinter::PrintObjCPropertyDecl(ObjCPropertyDecl *PDecl) {
-  if (PDecl->getPropertyImplementation() == ObjCPropertyDecl::Required)
-    Out << "@required\n";
-  else if (PDecl->getPropertyImplementation() == ObjCPropertyDecl::Optional)
-    Out << "@optional\n";
-  
-  Out << "@property";
-  if (PDecl->getPropertyAttributes() != ObjCPropertyDecl::OBJC_PR_noattr) {
-    bool first = true;
-    Out << " (";
-    if (PDecl->getPropertyAttributes() & 
-        ObjCPropertyDecl::OBJC_PR_readonly) {
-      Out << (first ? ' ' : ',') << "readonly";
-      first = false;
-  }
-      
-  if (PDecl->getPropertyAttributes() & ObjCPropertyDecl::OBJC_PR_getter) {
-    Out << (first ? ' ' : ',') << "getter = "
-        << PDecl->getGetterName().getAsString();
-    first = false;
-  }
-  if (PDecl->getPropertyAttributes() & ObjCPropertyDecl::OBJC_PR_setter) {
-    Out << (first ? ' ' : ',') << "setter = "
-        << PDecl->getSetterName().getAsString();
-    first = false;
-  }
-      
-  if (PDecl->getPropertyAttributes() & ObjCPropertyDecl::OBJC_PR_assign) {
-    Out << (first ? ' ' : ',') << "assign";
-    first = false;
-  }
-      
-  if (PDecl->getPropertyAttributes() &
-      ObjCPropertyDecl::OBJC_PR_readwrite) {
-    Out << (first ? ' ' : ',') << "readwrite";
-    first = false;
-  }
-      
-  if (PDecl->getPropertyAttributes() & ObjCPropertyDecl::OBJC_PR_retain) {
-    Out << (first ? ' ' : ',') << "retain";
-    first = false;
-  }
-      
-  if (PDecl->getPropertyAttributes() & ObjCPropertyDecl::OBJC_PR_copy) {
-    Out << (first ? ' ' : ',') << "copy";
-    first = false;
-  }
-      
-  if (PDecl->getPropertyAttributes() & 
-      ObjCPropertyDecl::OBJC_PR_nonatomic) {
-    Out << (first ? ' ' : ',') << "nonatomic";
-    first = false;
-  }
-  Out << " )";
-  }
-  Out << ' ' << PDecl->getType().getAsString()
-  << ' ' << PDecl->getNameAsString();
-    
-  Out << ";\n";
-}
-
-/// PrintObjCPropertyImplDecl - Print an objective-c property implementation
-/// declaration syntax.
-///
-void DeclPrinter::PrintObjCPropertyImplDecl(ObjCPropertyImplDecl *PID) {
-  if (PID->getPropertyImplementation() == ObjCPropertyImplDecl::Synthesize)
-    Out << "\n@synthesize ";
-  else
-    Out << "\n@dynamic ";
-  Out << PID->getPropertyDecl()->getNameAsString();
-  if (PID->getPropertyIvarDecl())
-    Out << "=" << PID->getPropertyIvarDecl()->getNameAsString();
-  Out << ";\n";
-}
-
-/// PrintTemplateParams - Print a template parameter list and recursively print
-/// it's underlying top-level definition.
-void DeclPrinter::PrintTemplateDecl(TemplateDecl *TD) {
-  // TODO: Write template parameters.
-  Out << "template <...> ";
-  PrintDecl(TD->getTemplatedDecl());
-}
-
-
-
-//===----------------------------------------------------------------------===//
-/// ASTPrinter - Pretty-printer of ASTs
-
-namespace {
-  class ASTPrinter : public ASTConsumer, public DeclPrinter {
-  public:
-    ASTPrinter(llvm::raw_ostream* o = NULL) : DeclPrinter(o) {}
-    
-    virtual void HandleTopLevelDecl(DeclGroupRef D) {
-      for (DeclGroupRef::iterator I = D.begin(), E = D.end(); I != E; ++I)
-        PrintDecl(*I);
+    virtual void HandleTranslationUnit(ASTContext &Context) {
+      PrintingPolicy Policy = Context.PrintingPolicy;
+      Policy.Dump = Dump;
+      Context.getTranslationUnitDecl()->print(Out, Context, Policy);
     }
   };
 } // end anonymous namespace
@@ -626,91 +88,8 @@
   return new ASTPrinterXML(out ? *out : llvm::outs());
 }
  
-//===----------------------------------------------------------------------===//
-/// ASTDumper - Low-level dumper of ASTs
-
-namespace {
-  class ASTDumper : public ASTConsumer, public DeclPrinter {
-    ASTContext *Ctx;
-    bool FullDump;
-
-  public:
-    explicit ASTDumper(bool FullDump) : DeclPrinter(), FullDump(FullDump) {}
-    
-    void Initialize(ASTContext &Context) {
-      Ctx = &Context;
-    }
-
-    virtual void HandleTopLevelDecl(DeclGroupRef D) {
-      if (FullDump)
-        return;
-      for (DeclGroupRef::iterator I = D.begin(), E = D.end(); I != E; ++I)
-        HandleTopLevelSingleDecl(*I);
-    }
-    void HandleTopLevelSingleDecl(Decl *D);
-
-    virtual void HandleTranslationUnit(ASTContext &Ctx) {
-      if (!FullDump)
-        return;
-
-      for (DeclContext::decl_iterator 
-             D = Ctx.getTranslationUnitDecl()->decls_begin(Ctx),
-             DEnd = Ctx.getTranslationUnitDecl()->decls_end(Ctx);
-           D != DEnd; 
-           ++D)
-        HandleTopLevelSingleDecl(*D);
-    }
-  };
-} // end anonymous namespace
-
-void ASTDumper::HandleTopLevelSingleDecl(Decl *D) {
-  if (FunctionDecl *FD = dyn_cast<FunctionDecl>(D)) {
-    PrintFunctionDeclStart(FD);
-    
-    if (Stmt *Body = FD->getBody(*Ctx)) {
-      Out << '\n';
-      // FIXME: convert dumper to use raw_ostream.
-      Body->dumpAll(Ctx->getSourceManager());
-      Out << '\n';
-    }
-  } else if (TypedefDecl *TD = dyn_cast<TypedefDecl>(D)) {
-    PrintTypeDefDecl(TD);
-  } else if (ObjCInterfaceDecl *OID = dyn_cast<ObjCInterfaceDecl>(D)) {
-    Out << "Read objc interface '" << OID->getNameAsString() << "'\n";
-  } else if (ObjCProtocolDecl *OPD = dyn_cast<ObjCProtocolDecl>(D)) {
-    Out << "Read objc protocol '" << OPD->getNameAsString() << "'\n";
-  } else if (ObjCCategoryDecl *OCD = dyn_cast<ObjCCategoryDecl>(D)) {
-    Out << "Read objc category '" << OCD->getNameAsString() << "'\n";
-  } else if (isa<ObjCForwardProtocolDecl>(D)) {
-    Out << "Read objc fwd protocol decl\n";
-  } else if (isa<ObjCClassDecl>(D)) {
-    Out << "Read objc fwd class decl\n";
-  } else if (isa<FileScopeAsmDecl>(D)) {
-    Out << "Read file scope asm decl\n";
-  } else if (ObjCMethodDecl* MD = dyn_cast<ObjCMethodDecl>(D)) {
-    Out << "Read objc method decl: '" << MD->getSelector().getAsString()
-    << "'\n";
-    if (Stmt *S = MD->getBody()) {
-      // FIXME: convert dumper to use raw_ostream.
-      S->dumpAll(Ctx->getSourceManager());
-      Out << '\n';
-    }
-  } else if (isa<ObjCImplementationDecl>(D)) {
-    Out << "Read objc implementation decl\n";
-  } else if (isa<ObjCCategoryImplDecl>(D)) {
-    Out << "Read objc category implementation decl\n";
-  } else if (isa<LinkageSpecDecl>(D)) {
-    Out << "Read linkage spec decl\n";
-  } else if (NamedDecl *ND = dyn_cast<NamedDecl>(D)) {
-    Out << "Read top-level variable decl: '" << ND->getNameAsString()
-    << "'\n";
-  } else {
-    assert(0 && "Unknown decl type!");
-  }
-}
-
-ASTConsumer *clang::CreateASTDumper(bool FullDump) { 
-  return new ASTDumper(FullDump); 
+ASTConsumer *clang::CreateASTDumper() { 
+  return new ASTPrinter(0, true); 
 }
 
 //===----------------------------------------------------------------------===//
@@ -718,10 +97,10 @@
 
 namespace {
   class ASTViewer : public ASTConsumer {
-    SourceManager *SM;
+    ASTContext *Context;
   public:
     void Initialize(ASTContext &Context) {
-      SM = &Context.getSourceManager();
+      this->Context = &Context;
     }
 
     virtual void HandleTopLevelDecl(DeclGroupRef D) {
@@ -735,7 +114,7 @@
 
 void ASTViewer::HandleTopLevelSingleDecl(Decl *D) {
   if (FunctionDecl *FD = dyn_cast<FunctionDecl>(D)) {
-    DeclPrinter().PrintFunctionDeclStart(FD);
+    FD->print(llvm::errs(), *Context);
     
     if (FD->getBodyIfAvailable()) {
       llvm::cerr << '\n';
@@ -746,7 +125,7 @@
   }
   
   if (ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(D)) {
-    DeclPrinter().PrintObjCMethodDecl(MD);
+    MD->print(llvm::errs(), *Context);
     
     if (MD->getBody()) {
       llvm::cerr << '\n';
diff --git a/lib/Frontend/DocumentXML.cpp b/lib/Frontend/DocumentXML.cpp
index ac1d7d2..7562d2a 100644
--- a/lib/Frontend/DocumentXML.cpp
+++ b/lib/Frontend/DocumentXML.cpp
@@ -566,6 +566,8 @@
       case LinkageSpecDecl::lang_cxx:  addAttribute("lang", "CXX");  break;
       default:                         assert(0 && "Unexpected lang id");
     }
+  } else if (isa<FileScopeAsmDecl>(D)) {
+    // FIXME: Implement this
   } else {
     assert(0 && "Unexpected decl");
   }
