[Lldb-commits] [lldb] r124703 - in /lldb/trunk: include/lldb/Expression/ASTDumper.h lldb.xcodeproj/project.pbxproj source/Expression/ASTDumper.cpp source/Expression/ClangExpressionDeclMap.cpp

Sean Callanan scallanan at apple.com
Tue Feb 1 15:43:26 PST 2011


Author: spyffe
Date: Tue Feb  1 17:43:26 2011
New Revision: 124703

URL: http://llvm.org/viewvc/llvm-project?rev=124703&view=rev
Log:
Added a new class, ASTDumper, that provides verbose
diagnostics of Clang AST classes for the purpose of
debugging the types LLDB produces for DWARF objects.

The ASTDumper is currently only used in log output
if you enable verbose mode in the expression log:

log enable -v lldb expr

Its output then appears in the log for external
variables used by the expr command.

Added:
    lldb/trunk/include/lldb/Expression/ASTDumper.h
    lldb/trunk/source/Expression/ASTDumper.cpp
Modified:
    lldb/trunk/lldb.xcodeproj/project.pbxproj
    lldb/trunk/source/Expression/ClangExpressionDeclMap.cpp

Added: lldb/trunk/include/lldb/Expression/ASTDumper.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/Expression/ASTDumper.h?rev=124703&view=auto
==============================================================================
--- lldb/trunk/include/lldb/Expression/ASTDumper.h (added)
+++ lldb/trunk/include/lldb/Expression/ASTDumper.h Tue Feb  1 17:43:26 2011
@@ -0,0 +1,171 @@
+//===-- ASTDumper.h ---------------------------------------------*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#include "clang/AST/DeclVisitor.h"
+#include "clang/AST/StmtVisitor.h"
+#include "clang/AST/TypeVisitor.h"
+
+#include "lldb/Core/Stream.h"
+#include "llvm/ADT/DenseSet.h"
+
+namespace lldb_private
+{
+
+//----------------------------------------------------------------------
+/// @class ASTDumper ASTDumper.h "lldb/Expression/ASTDumper.h"
+/// @brief Encapsulates a recursive dumper for Clang AST nodes.
+///
+/// ASTDumper contains a variety of methods for printing fields of Clang
+/// AST structures, for debugging purposes.  It prints the AST objects
+/// hierarchically:
+///
+/// ---
+/// class : InheritedClass
+/// someAccessor() : result
+/// accessorReturningObject() :
+///  class : ChildClass [object returned by accessorReturningObject]
+///  ...
+/// class : BaseClass [same object as InheritedClass]
+/// baseAccessor() : result
+///
+/// The output format is YAML.
+//----------------------------------------------------------------------
+class ASTDumper : 
+    public clang::DeclVisitor <ASTDumper, void>, 
+    public clang::StmtVisitor <ASTDumper, void>,
+    public clang::TypeVisitor <ASTDumper, void>
+{
+private:
+    ASTDumper (Stream &stream) :
+        m_stream(stream),
+        m_base_indentation(stream.GetIndentLevel()),
+        m_max_indentation(10)
+    {
+    }
+    
+    // MARK: Utility functions
+    
+    bool KeepDumping ()
+    {
+        return (m_stream.GetIndentLevel() - m_base_indentation <= m_max_indentation);
+    }
+    
+    void PushIndent()
+    {
+        m_stream.IndentMore(1);
+    }
+    
+    void PopIndent()
+    {
+        m_stream.IndentLess(1);
+    }
+    
+    bool Visiting (const void *entity)
+    {
+        return m_visited_entities.count(entity);
+    }
+    
+    void WillVisit (const void *entity)
+    {
+        m_visited_entities.insert(entity);
+    }
+    
+    void DidVisit (const void *entity)
+    {
+        m_visited_entities.erase(entity);
+    }
+    
+public:
+    // MARK: DeclVisitor
+    
+    void VisitDecl                  (clang::Decl *decl);
+    void VisitTranslationUnitDecl   (clang::TranslationUnitDecl *translation_unit_decl);
+    void VisitNamedDecl             (clang::NamedDecl *named_decl);
+    void VisitNamespaceDecl         (clang::NamespaceDecl *namespace_decl);
+    void VisitValueDecl             (clang::ValueDecl *value_decl);
+    void VisitDeclaratorDecl        (clang::DeclaratorDecl *declarator_decl);
+    void VisitVarDecl               (clang::VarDecl *var_decl);
+    void VisitTypeDecl              (clang::TypeDecl *type_decl);
+    void VisitTagDecl               (clang::TagDecl *tag_decl);
+    void VisitRecordDecl            (clang::RecordDecl *record_decl);
+    void VisitCXXRecordDecl         (clang::CXXRecordDecl *cxx_record_decl);
+    
+    // MARK: StmtVisitor
+    
+    // MARK: TypeVisitor
+    
+    void VisitType                  (const clang::Type *type);
+    void VisitReferenceType         (const clang::ReferenceType *reference_type);
+    void VisitLValueReferenceType   (const clang::LValueReferenceType *lvalue_reference_type);
+    void VisitPointerType           (const clang::PointerType *pointer_type);
+    void VisitTagType               (const clang::TagType *tag_type);
+    void VisitRecordType            (const clang::RecordType *record_type);
+
+private:
+    llvm::DenseSet <const void *>   m_visited_entities; ///< A set of all entities that have already been printed, to prevent loops
+    Stream                         &m_stream;           ///< A stream to print output to
+    unsigned                        m_base_indentation; ///< The indentation of m_stream when the ASTDumper was entered
+    unsigned                        m_max_indentation;  ///< The maximum depth of indentation (added to m_base_indentation)
+public:
+    //------------------------------------------------------------------
+    /// DumpDecl - Create an ASTDumper and use it to dump a Decl.
+    ///
+    /// @param[in] stream
+    ///     The stream to use when printing output.
+    ///
+    /// @param[in] decl
+    ///     The AST Decl to print.
+    //------------------------------------------------------------------
+    static void DumpDecl (Stream &stream, clang::Decl *decl)
+    {
+        ASTDumper dumper(stream);
+     
+        stream.Printf("---\n");
+        
+        dumper.::clang::DeclVisitor<ASTDumper, void>::Visit(decl);
+    }
+    
+    //------------------------------------------------------------------
+    /// DumpDecl - Create an ASTDumper and use it to dump a Stmt.
+    ///
+    /// @param[in] stream
+    ///     The stream to use when printing output.
+    ///
+    /// @param[in] stmt
+    ///     The AST Stmt to print.
+    //------------------------------------------------------------------
+    static void DumpStmt (Stream &stream, clang::Stmt *stmt)
+    {
+        ASTDumper dumper(stream);
+        
+        stream.Printf("---\n");
+        
+        dumper.::clang::StmtVisitor<ASTDumper, void>::Visit(stmt);
+    }
+    
+    //------------------------------------------------------------------
+    /// DumpDecl - Create an ASTDumper and use it to dump a Type.
+    ///
+    /// @param[in] stream
+    ///     The stream to use when printing output.
+    ///
+    /// @param[in] type
+    ///     The AST Type to print.
+    //------------------------------------------------------------------
+    static void DumpType (Stream &stream, clang::Type *type)
+    {
+        ASTDumper dumper(stream);
+        
+        stream.Printf("---\n");
+        
+        dumper.::clang::TypeVisitor<ASTDumper, void>::Visit(type);
+    }
+};
+
+} // namespace lldb_private

Modified: lldb/trunk/lldb.xcodeproj/project.pbxproj
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/lldb.xcodeproj/project.pbxproj?rev=124703&r1=124702&r2=124703&view=diff
==============================================================================
--- lldb/trunk/lldb.xcodeproj/project.pbxproj (original)
+++ lldb/trunk/lldb.xcodeproj/project.pbxproj Tue Feb  1 17:43:26 2011
@@ -318,6 +318,7 @@
 		26F5C32D10F3DFDD009D5894 /* libtermcap.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = 26F5C32B10F3DFDD009D5894 /* libtermcap.dylib */; };
 		26F5C37510F3F61B009D5894 /* libobjc.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = 26F5C37410F3F61B009D5894 /* libobjc.dylib */; };
 		26F5C39110F3FA26009D5894 /* CoreFoundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 26F5C39010F3FA26009D5894 /* CoreFoundation.framework */; };
+		4906FD4212F2255300A2A77C /* ASTDumper.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4906FD4012F2255300A2A77C /* ASTDumper.cpp */; };
 		491193521226386000578B7F /* ASTStructExtractor.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 491193501226386000578B7F /* ASTStructExtractor.cpp */; };
 		49307AAE11DEA4D90081F992 /* IRForTarget.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 49307AAD11DEA4D90081F992 /* IRForTarget.cpp */; };
 		49445C2612245E3600C11A81 /* ClangExpressionParser.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 49445C2512245E3600C11A81 /* ClangExpressionParser.cpp */; };
@@ -925,6 +926,8 @@
 		26F996A8119B79C300412154 /* ARM_GCC_Registers.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = ARM_GCC_Registers.h; path = source/Utility/ARM_GCC_Registers.h; sourceTree = "<group>"; };
 		26FE25221146CADE00F4085A /* GDBRemoteCommunication.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = GDBRemoteCommunication.cpp; path = "source/Plugins/Process/gdb-remote/GDBRemoteCommunication.cpp"; sourceTree = "<group>"; };
 		26FE25231146CADE00F4085A /* GDBRemoteCommunication.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = GDBRemoteCommunication.h; path = "source/Plugins/Process/gdb-remote/GDBRemoteCommunication.h"; sourceTree = "<group>"; };
+		4906FD4012F2255300A2A77C /* ASTDumper.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = ASTDumper.cpp; path = source/Expression/ASTDumper.cpp; sourceTree = "<group>"; };
+		4906FD4412F2257600A2A77C /* ASTDumper.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = ASTDumper.h; path = include/lldb/Expression/ASTDumper.h; sourceTree = "<group>"; };
 		4911934B1226383D00578B7F /* ASTStructExtractor.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = ASTStructExtractor.h; path = include/lldb/Expression/ASTStructExtractor.h; sourceTree = "<group>"; };
 		491193501226386000578B7F /* ASTStructExtractor.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = ASTStructExtractor.cpp; path = source/Expression/ASTStructExtractor.cpp; sourceTree = "<group>"; };
 		49307AAD11DEA4D90081F992 /* IRForTarget.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = IRForTarget.cpp; path = source/Expression/IRForTarget.cpp; sourceTree = "<group>"; };
@@ -1939,6 +1942,8 @@
 				497C86BD122823D800B54702 /* ClangUtilityFunction.cpp */,
 				26BC7DC310F1B79500F91463 /* DWARFExpression.h */,
 				26BC7ED810F1B86700F91463 /* DWARFExpression.cpp */,
+				4906FD4412F2257600A2A77C /* ASTDumper.h */,
+				4906FD4012F2255300A2A77C /* ASTDumper.cpp */,
 				49A8A3A311D568BF00AD3B68 /* ASTResultSynthesizer.h */,
 				49A8A39F11D568A300AD3B68 /* ASTResultSynthesizer.cpp */,
 				4911934B1226383D00578B7F /* ASTStructExtractor.h */,
@@ -2834,6 +2839,7 @@
 				B296983712C2FB98002D92C3 /* CommandObjectVersion.cpp in Sources */,
 				26D9FDC912F784FD0003F2EE /* EmulateInstruction.cpp in Sources */,
 				26D9FDCE12F7853F0003F2EE /* EmulateInstructionARM.cpp in Sources */,
+				4906FD4212F2255300A2A77C /* ASTDumper.cpp in Sources */,
 			);
 			runOnlyForDeploymentPostprocessing = 0;
 		};

Added: lldb/trunk/source/Expression/ASTDumper.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Expression/ASTDumper.cpp?rev=124703&view=auto
==============================================================================
--- lldb/trunk/source/Expression/ASTDumper.cpp (added)
+++ lldb/trunk/source/Expression/ASTDumper.cpp Tue Feb  1 17:43:26 2011
@@ -0,0 +1,545 @@
+//===-- ASTDumper.cpp -------------------------------------------*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#include "lldb/Expression/ASTDumper.h"
+
+using namespace lldb_private;
+using namespace clang;
+
+// MARK: Utility functions
+
+static const char* SfB (bool b)
+{
+    return b ? "True" : "False";
+}
+
+// MARK: DeclVisitor
+
+void ASTDumper::VisitDecl (clang::Decl *decl)
+{
+    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() : ");
+    
+    TranslationUnitDecl *translation_unit_decl = decl->getTranslationUnitDecl();
+    
+    if (translation_unit_decl)
+    {
+        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");
+        }
+    }
+    else
+    {
+        m_stream.Printf("~\n");
+    }
+    
+    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;
+    }
+}
+
+void ASTDumper::VisitTranslationUnitDecl (clang::TranslationUnitDecl *translation_unit_decl)
+{
+    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);
+}
+
+void ASTDumper::VisitNamedDecl (clang::NamedDecl *named_decl)
+{
+    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);
+}
+
+void ASTDumper::VisitNamespaceDecl (clang::NamespaceDecl *namespace_decl)
+{
+    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()));
+    
+    VisitNamedDecl (namespace_decl);
+}
+
+void ASTDumper::VisitValueDecl (clang::ValueDecl *value_decl)
+{
+    m_stream.Indent();  m_stream.Printf("class : ValueDecl\n");
+    m_stream.Indent();  m_stream.Printf("getType() : ");
+    if (value_decl->getType().getTypePtrOrNull())
+    {
+        const clang::Type *type_ptr = value_decl->getType().getTypePtr();
+        
+        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");
+    }
+    
+    VisitNamedDecl (value_decl);
+}
+
+void ASTDumper::VisitDeclaratorDecl (clang::DeclaratorDecl *declarator_decl)
+{
+    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("isDefinition() : %s\n", SfB(tag_decl->isDefinition()));
+    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("isPODType() : %s\n", SfB(type->isPODType()));
+    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_Pointer:          m_stream.Printf("STK_Pointer\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);
+}

Modified: lldb/trunk/source/Expression/ClangExpressionDeclMap.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Expression/ClangExpressionDeclMap.cpp?rev=124703&r1=124702&r2=124703&view=diff
==============================================================================
--- lldb/trunk/source/Expression/ClangExpressionDeclMap.cpp (original)
+++ lldb/trunk/source/Expression/ClangExpressionDeclMap.cpp Tue Feb  1 17:43:26 2011
@@ -21,6 +21,7 @@
 #include "lldb/Core/Log.h"
 #include "lldb/Core/Module.h"
 #include "lldb/Core/ValueObjectConstResult.h"
+#include "lldb/Expression/ASTDumper.h"
 #include "lldb/Expression/ClangASTSource.h"
 #include "lldb/Expression/ClangPersistentVariables.h"
 #include "lldb/Host/Endian.h"
@@ -1904,6 +1905,13 @@
         var_decl_print_stream.flush();
         
         log->Printf("Found variable %s, returned %s", 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());
+        }
     }
 }
 





More information about the lldb-commits mailing list