Improved logging, replacing the old ASTDumper (which
we never used) with a much simpler class that wraps
the relevant dump functions in Clang.  This class also
knows to disable external lookups on DeclContexts
being dumped so it should be safe to print incomplete
Decls.


git-svn-id: https://llvm.org/svn/llvm-project/llvdb/trunk@142359 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/source/Expression/ASTDumper.cpp b/source/Expression/ASTDumper.cpp
index 3f6104b..eafd69f 100644
--- a/source/Expression/ASTDumper.cpp
+++ b/source/Expression/ASTDumper.cpp
@@ -7,538 +7,118 @@
 //
 //===----------------------------------------------------------------------===//
 
+#include "lldb/Core/Log.h"
 #include "lldb/Expression/ASTDumper.h"
 
+#include "llvm/Support/raw_ostream.h"
+
 using namespace lldb_private;
-using namespace clang;
 
-// MARK: Utility functions
-
-static const char* SfB (bool b)
+ASTDumper::ASTDumper (clang::Decl *decl)
 {
-    return b ? "True" : "False";
+    clang::DeclContext *decl_ctx = llvm::dyn_cast<clang::DeclContext>(decl);
+    
+    bool has_external_lexical_storage;
+    bool has_external_visible_storage;
+    
+    if (decl_ctx)
+    {
+        has_external_lexical_storage = decl_ctx->hasExternalLexicalStorage();
+        has_external_visible_storage = decl_ctx->hasExternalVisibleStorage();
+        decl_ctx->setHasExternalLexicalStorage(false);
+        decl_ctx->setHasExternalVisibleStorage(false);
+    }
+    
+    llvm::raw_string_ostream os(m_dump);
+    decl->print (os);
+    os.flush();
+    
+    if (decl_ctx)
+    {
+        decl_ctx->setHasExternalLexicalStorage(has_external_lexical_storage);
+        decl_ctx->setHasExternalVisibleStorage(has_external_visible_storage);
+    }
 }
 
-// MARK: DeclVisitor
-
-void ASTDumper::VisitDecl (clang::Decl *decl)
+ASTDumper::ASTDumper (clang::DeclContext *decl_ctx)
 {
-    m_stream.Indent();  m_stream.Printf("class : Decl\n");
-    m_stream.Indent();  m_stream.Printf("getDeclKindName() : %s\n", decl->getDeclKindName());
-    m_stream.Indent();  m_stream.Printf("getTranslationUnitDecl() : ");
+    bool has_external_lexical_storage = decl_ctx->hasExternalLexicalStorage();
+    bool has_external_visible_storage = decl_ctx->hasExternalVisibleStorage();
     
-    TranslationUnitDecl *translation_unit_decl = decl->getTranslationUnitDecl();
+    decl_ctx->setHasExternalLexicalStorage(false);
+    decl_ctx->setHasExternalVisibleStorage(false);
     
-    if (translation_unit_decl)
+    if (clang::Decl *decl = llvm::dyn_cast<clang::Decl>(decl_ctx))
     {
-        if (KeepDumping() && !Visiting(translation_unit_decl))
-        {
-            m_stream.Printf("\n");
-            
-            PushIndent();
-            WillVisit(translation_unit_decl);
-            VisitTranslationUnitDecl(translation_unit_decl);
-            DidVisit(translation_unit_decl);
-            PopIndent();
-        }
-        else
-        {
-            m_stream.Printf("capped\n");
-        }
+        llvm::raw_string_ostream os(m_dump);
+        decl->print (os);
+        os.flush();
     }
     else
     {
-        m_stream.Printf("~\n");
+        m_dump.assign("<DeclContext is not a Decl>");
     }
     
-    m_stream.Indent();  m_stream.Printf("getAccess() : ");
-    switch (decl->getAccess())
-    {
-        default:            m_stream.Printf("~\n");
-        case AS_public:     m_stream.Printf("AS_public\n");
-        case AS_protected:  m_stream.Printf("AS_protected\n");
-        case AS_private:    m_stream.Printf("AS_private\n");
-        case AS_none:       m_stream.Printf("AS_none\n");
-    }
-    m_stream.Indent();  m_stream.Printf("getMaxAlignment() : %d\n", decl->getMaxAlignment());
-    m_stream.Indent();  m_stream.Printf("isInvalidDecl() : %s\n", SfB(decl->isInvalidDecl()));
-    m_stream.Indent();  m_stream.Printf("isImplicit() : %s\n", SfB(decl->isImplicit()));
-    m_stream.Indent();  m_stream.Printf("isUsed() : %s\n", SfB(decl->isUsed()));
-    m_stream.Indent();  m_stream.Printf("isOutOfLine() : %s\n", SfB(decl->isOutOfLine()));
-    m_stream.Indent();  m_stream.Printf("isCanonicalDecl() : %s\n", SfB(decl->isCanonicalDecl()));
-    m_stream.Indent();  m_stream.Printf("hasBody() : %s\n", SfB(decl->hasBody()));
-    m_stream.Indent();  m_stream.Printf("isTemplateParameter() : %s\n", SfB(decl->isTemplateParameter()));
-    m_stream.Indent();  m_stream.Printf("isTemplateParameterPack() : %s\n", SfB(decl->isTemplateParameterPack()));
-    m_stream.Indent();  m_stream.Printf("isParameterPack() : %s\n", SfB(decl->isParameterPack()));
-    m_stream.Indent();  m_stream.Printf("isFunctionOrFunctionTemplate() : %s\n", SfB(decl->isFunctionOrFunctionTemplate()));
-    m_stream.Indent();  m_stream.Printf("getFriendObjectKind() : ");
-    switch (decl->getFriendObjectKind())
-    {
-        default:                    m_stream.Printf("~\n");                 break;
-        case Decl::FOK_None:        m_stream.Printf("FOK_None\n");          break;
-        case Decl::FOK_Declared:    m_stream.Printf("FOK_Declared\n");      break;
-        case Decl::FOK_Undeclared:  m_stream.Printf("FOK_Undeclared\n");    break;
-    }
+    decl_ctx->setHasExternalLexicalStorage(has_external_lexical_storage);
+    decl_ctx->setHasExternalVisibleStorage(has_external_visible_storage);
 }
 
-void ASTDumper::VisitTranslationUnitDecl (clang::TranslationUnitDecl *translation_unit_decl)
+ASTDumper::ASTDumper (clang::Type *type)
 {
-    m_stream.Indent();  m_stream.Printf("class : TranslationUnitDecl\n");
-    m_stream.Indent();  m_stream.Printf("getAnonymousNamespace() : ");
-    
-    NamespaceDecl *anonymous_namespace = translation_unit_decl->getAnonymousNamespace();
-    
-    if (anonymous_namespace)
-    {
-        if (KeepDumping() && !Visiting(anonymous_namespace))
-        {
-            m_stream.Printf("\n");
-            
-            PushIndent();
-            WillVisit(anonymous_namespace);
-            VisitNamespaceDecl(anonymous_namespace);
-            DidVisit(anonymous_namespace);
-            PopIndent();
-        }
-        else
-        {
-            m_stream.Printf("capped\n");
-        }
-    }
-    else
-    {
-        m_stream.Printf("~\n");
-    }
-    
-    VisitDecl (translation_unit_decl);
+    m_dump = clang::QualType(type, 0).getAsString();
 }
 
-void ASTDumper::VisitNamedDecl (clang::NamedDecl *named_decl)
+ASTDumper::ASTDumper (clang::QualType type)
 {
-    m_stream.Indent();  m_stream.Printf("class : NamedDecl\n");
-    m_stream.Indent();  m_stream.Printf("getNameAsString() : %s\n", named_decl->getNameAsString().c_str());
-    m_stream.Indent();  m_stream.Printf("hasLinkage() : %s\n", SfB(named_decl->hasLinkage()));
-    m_stream.Indent();  m_stream.Printf("isCXXClassMember() : %s\n", SfB(named_decl->isCXXClassMember()));
-    m_stream.Indent();  m_stream.Printf("isCXXInstanceMember() : %s\n", SfB(named_decl->isCXXClassMember()));
-    m_stream.Indent();  m_stream.Printf("getVisibility() : ");
-    switch (named_decl->getVisibility())
-    {
-        default:                    m_stream.Printf("~\n"); break;
-        case HiddenVisibility:      m_stream.Printf("HiddenVisibility\n"); break;
-        case ProtectedVisibility:   m_stream.Printf("ProtectedVisibility\n"); break;
-        case DefaultVisibility:     m_stream.Printf("DefaultVisibility\n"); break;
-    }
-    m_stream.Indent();  m_stream.Printf("getUnderlyingDecl() : ");
-    
-    NamedDecl *underlying_decl = named_decl->getUnderlyingDecl();
-    
-    if (underlying_decl)
-    {
-        if (KeepDumping() && !Visiting(underlying_decl))
-        {
-            m_stream.Printf("\n");
-            
-            PushIndent();
-            WillVisit(underlying_decl);
-            ::clang::DeclVisitor<ASTDumper, void>::Visit(underlying_decl);
-            DidVisit(underlying_decl);
-            PopIndent();
-        }
-        else
-        {
-            m_stream.Printf("capped\n");
-        }
-    }
-    else
-    {
-        m_stream.Printf("~\n");
-    }
-    
-    VisitDecl (named_decl);
+    m_dump = type.getAsString();
 }
 
-void ASTDumper::VisitNamespaceDecl (clang::NamespaceDecl *namespace_decl)
+ASTDumper::ASTDumper (lldb::clang_type_t type)
 {
-    m_stream.Indent();  m_stream.Printf("class : NamespaceDecl\n");
-    m_stream.Indent();  m_stream.Printf("isAnonymousNamespace() : %s\n", SfB(namespace_decl->isAnonymousNamespace()));
-    m_stream.Indent();  m_stream.Printf("isInline() : %s\n", SfB(namespace_decl->isInline()));
-    m_stream.Indent();  m_stream.Printf("isOriginalNamespace() : %s\n", SfB(namespace_decl->isOriginalNamespace()));
+    m_dump = clang::QualType::getFromOpaquePtr(type).getAsString();
+}
     
-    VisitNamedDecl (namespace_decl);
+std::string ASTDumper::AsString()
+{
+    return m_dump;
 }
 
-void ASTDumper::VisitValueDecl (clang::ValueDecl *value_decl)
+void ASTDumper::ToSTDERR()
 {
-    m_stream.Indent();  m_stream.Printf("class : ValueDecl\n");
-    m_stream.Indent();  m_stream.Printf("getType() : ");
-    if (value_decl->getType().getTypePtrOrNull())
+    fprintf(stderr, "%s\n", m_dump.c_str());
+}
+
+void ASTDumper::ToLog(lldb::LogSP &log, const char *prefix)
+{
+    size_t len = m_dump.length() + 1;
+    
+    char *alloc = (char*)malloc(len);
+    char *str = alloc;
+    
+    memcpy(str, m_dump.c_str(), len);
+    
+    char *end = NULL;
+    
+    end = strchr(str, '\n');
+    
+    while (end)
     {
-        const clang::Type *type_ptr = value_decl->getType().getTypePtr();
+        *end = '\0';
         
-        if (KeepDumping() && !Visiting(type_ptr))
-        {
-            m_stream.Printf("\n");
-            
-            PushIndent();
-            WillVisit(type_ptr);
-            ::clang::TypeVisitor<ASTDumper, void>::Visit(type_ptr);
-            DidVisit(type_ptr);
-            PopIndent();
-        }
-        else
-        {
-            m_stream.Printf("capped\n");
-        }
-    }
-    else
-    {
-        m_stream.Printf("~\n");
+        log->Printf("%s%s", prefix, str);
+        
+        *end = '\n';
+        
+        str = end + 1;
+        end = strchr(str, '\n');
     }
     
-    VisitNamedDecl (value_decl);
+    log->Printf("%s%s", prefix, str);
+                    
+    free(alloc);
 }
 
-void ASTDumper::VisitDeclaratorDecl (clang::DeclaratorDecl *declarator_decl)
+void ASTDumper::ToStream(lldb::StreamSP &stream)
 {
-    m_stream.Indent();  m_stream.Printf("class : DeclaratorDecl\n");
-    VisitValueDecl (declarator_decl);
-}
-
-void ASTDumper::VisitVarDecl (clang::VarDecl *var_decl)
-{
-    m_stream.Indent();  m_stream.Printf("class : VarDecl\n");
-    VisitDeclaratorDecl (var_decl);
-}
-
-void ASTDumper::VisitTypeDecl (clang::TypeDecl *type_decl)
-{
-    m_stream.Indent();  m_stream.Printf("class : TypeDecl\n");
-    m_stream.Indent();  m_stream.Printf("getTypeForDecl() : ");
-    
-    const clang::Type *type_for_decl = type_decl->getTypeForDecl();
-    
-    if (type_for_decl)
-    {
-        if (KeepDumping() && !Visiting(type_for_decl))
-        {
-            m_stream.Printf("\n");
-            
-            PushIndent();
-            WillVisit(type_for_decl);
-            ::clang::TypeVisitor<ASTDumper, void>::Visit(type_for_decl);
-            DidVisit(type_for_decl);
-            PopIndent();
-        }
-        else
-        {
-            m_stream.Printf("capped\n");
-        }
-    }
-    else
-    {
-        m_stream.Printf("~\n");
-    }
-    
-    VisitNamedDecl (type_decl);
-}
-
-void ASTDumper::VisitTagDecl (clang::TagDecl *tag_decl)
-{
-    m_stream.Indent();  m_stream.Printf("class : TagDecl\n");
-    m_stream.Indent();  m_stream.Printf("getDefinition() : %s\n", SfB((bool)tag_decl->getDefinition()));
-    m_stream.Indent();  m_stream.Printf("isBeingDefined() : %s\n", SfB(tag_decl->isBeingDefined()));
-    m_stream.Indent();  m_stream.Printf("isEmbeddedInDeclarator() : %s\n", SfB(tag_decl->isEmbeddedInDeclarator()));
-    m_stream.Indent();  m_stream.Printf("isDependentType() : %s\n", SfB(tag_decl->isDependentType()));
-    m_stream.Indent();  m_stream.Printf("getDefinition() : ");
-    
-    TagDecl *definition = tag_decl->getDefinition();
-    
-    if (definition)
-    {
-        if (KeepDumping() && !Visiting(definition))
-        {
-            m_stream.Printf("\n");
-            
-            PushIndent();
-            WillVisit(definition);
-            ::clang::DeclVisitor<ASTDumper, void>::Visit(tag_decl->getDefinition());
-            DidVisit(definition);
-            PopIndent();
-        }
-        else
-        {
-            m_stream.Printf("capped\n");
-        }
-    }
-    else
-    {
-        m_stream.Printf("~\n");
-    }
-    m_stream.Indent();  m_stream.Printf("getKindName() : %s\n", tag_decl->getKindName());
-    
-    VisitTypeDecl(tag_decl);
-}
-
-void ASTDumper::VisitRecordDecl (clang::RecordDecl *record_decl)
-{
-    m_stream.Indent();  m_stream.Printf("class : RecordDecl\n");
-    m_stream.Indent();  m_stream.Printf("hasFlexibleArrayMember() : %s\n", SfB(record_decl->hasFlexibleArrayMember()));
-    m_stream.Indent();  m_stream.Printf("isAnonymousStructOrUnion() : %s\n", SfB(record_decl->isAnonymousStructOrUnion()));
-    m_stream.Indent();  m_stream.Printf("hasObjectMember() : %s\n", SfB(record_decl->hasObjectMember()));
-    m_stream.Indent();  m_stream.Printf("isInjectedClassName() : %s\n", SfB(record_decl->isInjectedClassName()));
-    m_stream.Indent();  m_stream.Printf("field_begin() ... field_end() : ");
-    if (KeepDumping())
-    {
-        if (record_decl->field_empty())
-        {
-            m_stream.Printf("~\n");
-        }
-        else
-        {
-            m_stream.Printf("\n");
-            PushIndent();
-            for (RecordDecl::field_iterator iter = record_decl->field_begin(), end_iter = record_decl->field_end();
-                 iter != end_iter;
-                 ++iter)
-            {
-                m_stream.Indent();  m_stream.Printf("- field:\n");
-                PushIndent();
-                if (Visiting (*iter))
-                {
-                    m_stream.Indent();  m_stream.Printf("capped\n");
-                }
-                else
-                {
-                    WillVisit(*iter);
-                    ::clang::DeclVisitor<ASTDumper, void>::Visit(*iter);
-                    DidVisit(*iter);
-                }
-                PopIndent();
-            }
-            PopIndent();
-        }
-    }
-    else
-    {
-        m_stream.Printf("capped\n");
-    }
-    
-    VisitTagDecl (record_decl);
-}
-
-void ASTDumper::VisitCXXRecordDecl (clang::CXXRecordDecl *cxx_record_decl)
-{
-    m_stream.Indent();  m_stream.Printf("class : CXXRecordDecl\n");
-    m_stream.Indent();  m_stream.Printf("isDynamicClass() : %s\n", SfB(cxx_record_decl->isDynamicClass()));
-    m_stream.Indent();  m_stream.Printf("bases_begin() ... bases_end() : ");
-    if (KeepDumping())
-    {
-        if (cxx_record_decl->bases_begin() == cxx_record_decl->bases_end())
-        {
-            m_stream.Printf("~\n");
-        }
-        else
-        {
-            m_stream.Printf("\n");
-            PushIndent();
-            for (CXXRecordDecl::base_class_iterator iter = cxx_record_decl->bases_begin(), end_iter = cxx_record_decl->bases_end();
-                 iter != end_iter;
-                 ++iter)
-            {
-                m_stream.Indent();  m_stream.Printf("- CXXBaseSpecifier:\n");
-                PushIndent();
-                m_stream.Indent();  m_stream.Printf("isVirtual() : %s\n", SfB(iter->isVirtual()));
-                m_stream.Indent();  m_stream.Printf("isBaseOfClass() : %s\n", SfB(iter->isBaseOfClass()));
-                m_stream.Indent();  m_stream.Printf("isPackExpansion() : %s\n", SfB(iter->isPackExpansion()));
-                m_stream.Indent();  m_stream.Printf("getAccessSpecifier() : ");
-                switch (iter->getAccessSpecifier())
-                {
-                    default:                    m_stream.Printf("~\n"); break;
-                    case clang::AS_none:        m_stream.Printf("AS_none\n"); break;
-                    case clang::AS_private:     m_stream.Printf("AS_private\n"); break;
-                    case clang::AS_protected:   m_stream.Printf("AS_protected\n"); break;
-                    case clang::AS_public:      m_stream.Printf("AS_public\n"); break;
-                }
-                m_stream.Indent();  m_stream.Printf("getType() : ");
-                const clang::Type *base_type = iter->getType().getTypePtr();
-                
-                if (Visiting(base_type))
-                {
-                    m_stream.Printf("capped\n");
-                }
-                else
-                {
-                    m_stream.Printf("\n");
-                    PushIndent();
-                    WillVisit(base_type);
-                    ::clang::TypeVisitor<ASTDumper, void>::Visit(base_type);
-                    DidVisit(base_type);
-                    PopIndent();
-                }
-                PopIndent();
-            }
-            PopIndent();
-        }
-    }
-    else
-    {
-        m_stream.Printf("capped\n");
-    }
-    
-    VisitRecordDecl(cxx_record_decl);
-}
-
-// MARK: TypeVisitor
-
-void ASTDumper::VisitType (const clang::Type *type)
-{
-    m_stream.Indent();  m_stream.Printf("class : Type\n");
-    m_stream.Indent();  m_stream.Printf("getTypeClass() : ");
-    switch (type->getTypeClass())
-    {
-        default:    m_stream.Printf("~\n"); break;
-#define TYPE(Class, Base) case clang::Type::Class: m_stream.Printf("%s\n", #Class); break;
-#define ABSTRACT_TYPE(Class, Base)
-#include "clang/AST/TypeNodes.def"
-    }
-    m_stream.Indent();  m_stream.Printf("isFromAST() : %s\n", SfB(type->isFromAST()));
-    m_stream.Indent();  m_stream.Printf("containsUnexpandedParameterPack() : %s\n", SfB(type->containsUnexpandedParameterPack()));
-    m_stream.Indent();  m_stream.Printf("isCanonicalUnqualified() : %s\n", SfB(type->isCanonicalUnqualified()));
-    m_stream.Indent();  m_stream.Printf("isIncompleteType() : %s\n", SfB(type->isIncompleteType()));
-    m_stream.Indent();  m_stream.Printf("isObjectType() : %s\n", SfB(type->isObjectType()));
-    m_stream.Indent();  m_stream.Printf("isLiteralType() : %s\n", SfB(type->isLiteralType()));
-    m_stream.Indent();  m_stream.Printf("isBuiltinType() : %s\n", SfB(type->isBuiltinType()));
-    m_stream.Indent();  m_stream.Printf("isPlaceholderType() : %s\n", SfB(type->isPlaceholderType()));
-    m_stream.Indent();  m_stream.Printf("isScalarType() : %s\n", SfB(type->isScalarType()));
-    m_stream.Indent();  m_stream.Printf("getScalarTypeKind() : ");
-    if (type->isScalarType())
-    {
-        switch (type->getScalarTypeKind())
-        {
-            default:                                m_stream.Printf("~\n"); break;
-            case clang::Type::STK_CPointer:         m_stream.Printf("STK_CPointer\n"); break;
-            case clang::Type::STK_MemberPointer:    m_stream.Printf("STK_MemberPointer\n"); break;
-            case clang::Type::STK_Bool:             m_stream.Printf("STK_Bool\n"); break;
-            case clang::Type::STK_Integral:         m_stream.Printf("STK_Integral\n"); break;
-            case clang::Type::STK_Floating:         m_stream.Printf("STK_Floating\n"); break;
-            case clang::Type::STK_IntegralComplex:  m_stream.Printf("STK_IntegralComplex\n"); break;
-            case clang::Type::STK_FloatingComplex:  m_stream.Printf("STK_FloatingComplex\n"); break;
-        }
-    }
-    else
-    {
-        m_stream.Printf("~\n");
-    }
-    // ...
-}
-
-void ASTDumper::VisitReferenceType(const clang::ReferenceType *reference_type)
-{
-    m_stream.Indent();  m_stream.Printf("class : ReferenceType\n");
-    m_stream.Indent();  m_stream.Printf("isSpelledAsLValue() : %s\n", SfB(reference_type->isSpelledAsLValue()));
-    m_stream.Indent();  m_stream.Printf("isInnerRef() : %s\n", SfB(reference_type->isInnerRef()));
-    m_stream.Indent();  m_stream.Printf("getPointeeType() : ");
-    
-    const clang::Type *pointee_type = reference_type->getPointeeType().getTypePtrOrNull();
-    
-    if (pointee_type)
-    {
-        if (KeepDumping() && !Visiting(pointee_type))
-        {
-            m_stream.Printf("\n");
-            
-            PushIndent();
-            WillVisit(pointee_type);
-            ::clang::TypeVisitor<ASTDumper, void>::Visit(pointee_type);
-            DidVisit(pointee_type);
-            PopIndent();
-        }
-        else
-        {
-            m_stream.Printf("capped\n");
-        }
-    }
-    else
-    {
-        m_stream.Printf("~\n");
-    }
-    VisitType(reference_type);
-}
-
-void ASTDumper::VisitLValueReferenceType(const clang::LValueReferenceType *lvalue_reference_type)
-{
-    m_stream.Indent();  m_stream.Printf("class : LValueReferenceType\n");
-    m_stream.Indent();  m_stream.Printf("isSugared() : %s\n", SfB(lvalue_reference_type->isSugared()));
-    VisitReferenceType(lvalue_reference_type);
-}
-
-void ASTDumper::VisitPointerType(const clang::PointerType *pointer_type)
-{
-    m_stream.Indent();  m_stream.Printf("class : PointerType\n");
-    m_stream.Indent();  m_stream.Printf("getPointeeType() : ");
-    
-    const clang::Type *pointee_type = pointer_type->getPointeeType().getTypePtrOrNull();
-    
-    if (pointee_type)
-    {
-        if (KeepDumping() && !Visiting(pointee_type))
-        {
-            m_stream.Printf("\n");
-            
-            PushIndent();
-            WillVisit(pointee_type);
-            ::clang::TypeVisitor<ASTDumper, void>::Visit(pointee_type);
-            DidVisit(pointee_type);
-            PopIndent();
-        }
-        else
-        {
-            m_stream.Printf("capped\n");
-        }
-    }
-    else
-    {
-        m_stream.Printf("~\n");
-    }
-    m_stream.Indent();  m_stream.Printf("isSugared() : %s\n", SfB (pointer_type->isSugared()));
-    VisitType(pointer_type);
-}
-
-void ASTDumper::VisitTagType(const clang::TagType *tag_type)
-{
-    m_stream.Indent();  m_stream.Printf("class : TagType\n");
-    m_stream.Indent();  m_stream.Printf("getDecl() : ");
-    
-    Decl *decl = tag_type->getDecl();
-    
-    if (decl)
-    {
-        if (KeepDumping() && !Visiting(decl))
-        {
-            m_stream.Printf("\n");
-            
-            PushIndent();
-            WillVisit(decl);
-            ::clang::DeclVisitor<ASTDumper, void>::Visit(decl);
-            DidVisit(decl);
-            PopIndent();
-        }
-        else
-        {
-            m_stream.Printf("capped\n");
-        }
-    }
-    else
-    {
-        m_stream.Printf("~\n");
-    }
-    m_stream.Indent();  m_stream.Printf("isBeingDefined() : %s\n", SfB(tag_type->isBeingDefined()));
-    VisitType(tag_type);
-}
-
-void ASTDumper::VisitRecordType(const clang::RecordType *record_type)
-{
-    m_stream.Indent();  m_stream.Printf("class : RecordType\n");
-    m_stream.Indent();  m_stream.Printf("hasConstFields() : %s\n", SfB(record_type->hasConstFields()));
-    VisitTagType(record_type);
+    stream->PutCString(m_dump.c_str());
 }
diff --git a/source/Expression/ClangExpressionDeclMap.cpp b/source/Expression/ClangExpressionDeclMap.cpp
index fc2dce8..d83613e 100644
--- a/source/Expression/ClangExpressionDeclMap.cpp
+++ b/source/Expression/ClangExpressionDeclMap.cpp
@@ -43,7 +43,6 @@
 #include "lldb/Target/StackFrame.h"
 #include "lldb/Target/Target.h"
 #include "lldb/Target/Thread.h"
-#include "llvm/Support/raw_ostream.h"
 
 using namespace lldb;
 using namespace lldb_private;
@@ -2181,13 +2180,11 @@
             
             if (log)
             {
-                StreamString type_stream;
-                class_user_type.DumpTypeCode(&type_stream);
-                type_stream.Flush();
-                log->Printf("  FEVD[%u] Adding type for $__lldb_class: %s", current_id, type_stream.GetString().c_str());
+                std::string type_string = ASTDumper(pointer_target_qual_type).AsString();
+                log->Printf("  FEVD[%u] Adding type for $__lldb_class: %s", current_id, type_string.c_str());
             }
             
-            AddOneType(context, class_user_type, true);
+            AddOneType(context, class_user_type, current_id, true);
             
             return;
         }
@@ -2234,13 +2231,11 @@
             
             if (log)
             {
-                StreamString type_stream;
-                class_user_type.DumpTypeCode(&type_stream);
-                type_stream.Flush();
-                log->Printf("  FEVD[%u] Adding type for $__lldb_objc_class: %s", current_id, type_stream.GetString().c_str());
+                std::string type_string = ASTDumper(pointer_target_type).AsString();
+                log->Printf("  FEVD[%u] Adding type for $__lldb_objc_class: %s", current_id, type_string.c_str());
             }
             
-            AddOneType(context, class_user_type, false);
+            AddOneType(context, class_user_type, current_id, false);
             
             return;
         }
@@ -2298,12 +2293,14 @@
         if (m_parser_vars->m_exe_ctx->GetRegisterContext())
         {
             const RegisterInfo *reg_info(m_parser_vars->m_exe_ctx->GetRegisterContext()->GetRegisterInfoByName(reg_name));
-            
-            if (log)
-                log->Printf("  FEVD[%u] Found register %s", current_id, reg_info->name);
-            
+                        
             if (reg_info)
+            {
+                if (log)
+                    log->Printf("  FEVD[%u] Found register %s", current_id, reg_info->name);
+                
                 AddOneRegister(context, reg_info, current_id);
+            }
         }
     }
     else
@@ -2512,7 +2509,7 @@
         TypeFromUser user_type(type_sp->GetClangFullType(),
                                type_sp->GetClangAST());
             
-        AddOneType(context, user_type, false);
+        AddOneType(context, user_type, current_id, false);
     }
 }
 
@@ -2535,6 +2532,9 @@
     static unsigned int invocation_id = 0;
     unsigned int current_id = invocation_id++;
     
+    if (current_id == 1686)
+        fprintf(stderr, "here\n");
+    
     if (log)
     {
         if (const NamedDecl *context_named_decl = dyn_cast<NamedDecl>(context_decl))
@@ -2566,12 +2566,9 @@
         return ELR_Failure;
     
     if (log)
-    {
-        std::string decl_print_string;
-        llvm::raw_string_ostream decl_print_stream(decl_print_string);
-        original_decl->print(decl_print_stream);
-        decl_print_stream.flush();
-        log->Printf("  FELD[%u] Original decl:\n%s", current_id, decl_print_string.c_str());
+    {       
+        log->Printf("  FELD[%u] Original decl:", current_id);
+        ASTDumper(original_decl).ToLog(log, "    ");
     }
     
     if (TagDecl *original_tag_decl = dyn_cast<TagDecl>(original_decl))
@@ -2597,10 +2594,7 @@
         {
             if (log)
             {
-                std::string decl_print_string;
-                llvm::raw_string_ostream decl_print_stream(decl_print_string);
-                decl->print(decl_print_stream);
-                decl_print_stream.flush();
+                std::string decl_print_string = ASTDumper(decl).AsString();
                 
                 if (const NamedDecl *context_named_decl = dyn_cast<NamedDecl>(context_decl))
                     log->Printf("  FELD[%d] Adding [to %s] lexical decl %s", current_id, context_named_decl->getNameAsString().c_str(), decl_print_string.c_str());
@@ -2785,19 +2779,9 @@
     
     if (log)
     {
-        std::string var_decl_print_string;
-        llvm::raw_string_ostream var_decl_print_stream(var_decl_print_string);
-        var_decl->print(var_decl_print_stream);
-        var_decl_print_stream.flush();
+        std::string var_decl_print_string = ASTDumper(var_decl).AsString();
         
         log->Printf("  FEVD[%u] Found variable %s, returned %s", current_id, decl_name.c_str(), var_decl_print_string.c_str());
-
-        //if (log->GetVerbose())
-        //{
-        //    StreamString var_decl_dump_string;
-        //    ASTDumper::DumpDecl(var_decl_dump_string, var_decl);
-        //    log->Printf("%s\n", var_decl_dump_string.GetData());
-        //}
     }
 }
 
@@ -2825,10 +2809,7 @@
     
     if (log)
     {
-        std::string var_decl_print_string;
-        llvm::raw_string_ostream var_decl_print_stream(var_decl_print_string);
-        var_decl->print(var_decl_print_stream);
-        var_decl_print_stream.flush();
+        std::string var_decl_print_string = ASTDumper(var_decl).AsString();
         
         log->Printf("  FEVD[%u] Added pvar %s, returned %s", current_id, pvar_sp->GetName().GetCString(), var_decl_print_string.c_str());
     }
@@ -2887,19 +2868,9 @@
     
     if (log)
     {
-        std::string var_decl_print_string;
-        llvm::raw_string_ostream var_decl_print_stream(var_decl_print_string);
-        var_decl->print(var_decl_print_stream);
-        var_decl_print_stream.flush();
+        std::string var_decl_print_string = ASTDumper(var_decl).AsString();
         
         log->Printf("  FEVD[%u] Found variable %s, returned %s", current_id, decl_name.c_str(), var_decl_print_string.c_str());
-        
-        //if (log->GetVerbose())
-        //{
-        //    StreamString var_decl_dump_string;
-        //    ASTDumper::DumpDecl(var_decl_dump_string, var_decl);
-        //    log->Printf("%s\n", var_decl_dump_string.GetData());
-        //}
     }
 }
 
@@ -2931,10 +2902,7 @@
             
             if (log)
             {
-                std::string var_decl_print_string;
-                llvm::raw_string_ostream var_decl_print_stream(var_decl_print_string);
-                var_decl->print(var_decl_print_stream);
-                var_decl_print_stream.flush();
+                std::string var_decl_print_string = ASTDumper((clang::Decl*)var_decl).AsString();
             
                 log->Printf("Variable of unknown type now has Decl %s", var_decl_print_string.c_str());
             }
@@ -2997,10 +2965,7 @@
     
     if (log && log->GetVerbose())
     {
-        std::string var_decl_print_string;
-        llvm::raw_string_ostream var_decl_print_stream(var_decl_print_string);
-        var_decl->print(var_decl_print_stream);
-        var_decl_print_stream.flush();
+        std::string var_decl_print_string = ASTDumper(var_decl).AsString();
         
         log->Printf("  FEVD[%d] Added register %s, returned %s", current_id, context.m_decl_name.getAsString().c_str(), var_decl_print_string.c_str());
     }
@@ -3108,10 +3073,7 @@
         
     if (log)
     {
-        std::string fun_decl_print_string;
-        llvm::raw_string_ostream fun_decl_print_stream(fun_decl_print_string);
-        fun_decl->print(fun_decl_print_stream);
-        fun_decl_print_stream.flush();
+        std::string fun_decl_print_string = ASTDumper(fun_decl).AsString();
         
         log->Printf("  FEVD[%u] Found %s function %s, returned %s", 
                     current_id,