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. llvm-svn: 142359
This commit is contained in:
parent
4205feffcd
commit
35c7f98734
|
@ -16,156 +16,22 @@
|
|||
|
||||
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>
|
||||
|
||||
class ASTDumper
|
||||
{
|
||||
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
|
||||
ASTDumper (clang::Decl *decl);
|
||||
ASTDumper (clang::DeclContext *decl_ctx);
|
||||
ASTDumper (clang::Type *type);
|
||||
ASTDumper (clang::QualType type);
|
||||
ASTDumper (lldb::clang_type_t type);
|
||||
|
||||
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);
|
||||
|
||||
std::string AsString();
|
||||
void ToSTDERR();
|
||||
void ToLog(lldb::LogSP &log, const char *prefix);
|
||||
void ToStream(lldb::StreamSP &stream);
|
||||
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);
|
||||
}
|
||||
std::string m_dump;
|
||||
};
|
||||
|
||||
} // namespace lldb_private
|
||||
|
|
|
@ -1076,7 +1076,7 @@ private:
|
|||
AddOneType (NameSearchContext &context,
|
||||
TypeFromUser &type,
|
||||
unsigned int current_id,
|
||||
bool add_method = false);
|
||||
bool add_method);
|
||||
|
||||
//------------------------------------------------------------------
|
||||
/// Actually do the task of materializing or dematerializing the struct.
|
||||
|
|
|
@ -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());
|
||||
}
|
||||
|
|
|
@ -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 @@ ClangExpressionDeclMap::FindExternalVisibleDecls (NameSearchContext &context,
|
|||
|
||||
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 @@ ClangExpressionDeclMap::FindExternalVisibleDecls (NameSearchContext &context,
|
|||
|
||||
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 @@ ClangExpressionDeclMap::FindExternalVisibleDecls (NameSearchContext &context,
|
|||
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 @@ ClangExpressionDeclMap::FindExternalVisibleDecls (NameSearchContext &context,
|
|||
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 @@ ClangExpressionDeclMap::FindExternalLexicalDecls (const DeclContext *decl_contex
|
|||
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 @@ ClangExpressionDeclMap::FindExternalLexicalDecls (const DeclContext *decl_contex
|
|||
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 @@ ClangExpressionDeclMap::FindExternalLexicalDecls (const DeclContext *decl_contex
|
|||
{
|
||||
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 @@ ClangExpressionDeclMap::AddOneVariable (NameSearchContext &context, VariableSP v
|
|||
|
||||
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 @@ ClangExpressionDeclMap::AddOneVariable(NameSearchContext &context,
|
|||
|
||||
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 @@ ClangExpressionDeclMap::AddOneGenericVariable(NameSearchContext &context,
|
|||
|
||||
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 @@ ClangExpressionDeclMap::ResolveUnknownTypes()
|
|||
|
||||
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 @@ ClangExpressionDeclMap::AddOneRegister (NameSearchContext &context,
|
|||
|
||||
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 @@ ClangExpressionDeclMap::AddOneFunction (NameSearchContext &context,
|
|||
|
||||
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,
|
||||
|
|
Loading…
Reference in New Issue