aboutsummaryrefslogtreecommitdiff
path: root/lib/AST/ASTDumper.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'lib/AST/ASTDumper.cpp')
-rw-r--r--lib/AST/ASTDumper.cpp898
1 files changed, 761 insertions, 137 deletions
diff --git a/lib/AST/ASTDumper.cpp b/lib/AST/ASTDumper.cpp
index 51d0f26c56..31331f1f9d 100644
--- a/lib/AST/ASTDumper.cpp
+++ b/lib/AST/ASTDumper.cpp
@@ -12,11 +12,12 @@
//
//===----------------------------------------------------------------------===//
-#include "clang/AST/PrettyPrinter.h"
#include "clang/AST/ASTContext.h"
#include "clang/AST/DeclCXX.h"
#include "clang/AST/DeclObjC.h"
+#include "clang/AST/DeclVisitor.h"
#include "clang/AST/StmtVisitor.h"
+#include "clang/Basic/Module.h"
#include "clang/Basic/SourceManager.h"
#include "llvm/Support/raw_ostream.h"
using namespace clang;
@@ -26,7 +27,8 @@ using namespace clang;
//===----------------------------------------------------------------------===//
namespace {
- class ASTDumper : public StmtVisitor<ASTDumper> {
+ class ASTDumper
+ : public DeclVisitor<ASTDumper>, public StmtVisitor<ASTDumper> {
SourceManager *SM;
raw_ostream &OS;
unsigned IndentLevel;
@@ -63,10 +65,78 @@ namespace {
// Utilities
void indent();
void unindent();
- void dumpSourceRange(const Stmt *Node);
+ void dumpPointer(const void *Ptr);
+ void dumpSourceRange(SourceRange R);
void dumpLocation(SourceLocation Loc);
+ void dumpBareType(QualType T);
void dumpType(QualType T);
- void dumpDeclRef(Decl *node);
+ void dumpBareDeclRef(Decl *node);
+ void dumpDeclRef(Decl *node, const char *Label = NULL);
+ void dumpName(NamedDecl *D);
+ void dumpDeclContext(DeclContext *DC);
+
+ // C++ Utilities
+ void dumpAccessSpecifier(AccessSpecifier AS);
+ void dumpCXXCtorInitializer(CXXCtorInitializer *Init);
+ void dumpTemplateParameters(TemplateParameterList *TPL);
+ void dumpTemplateArgumentListInfo(const TemplateArgumentListInfo &TALI);
+ void dumpTemplateArgumentLoc(const TemplateArgumentLoc &A);
+ void dumpTemplateArgumentList(const TemplateArgumentList &TAL);
+ void dumpTemplateArgument(const TemplateArgument &A,
+ SourceRange R = SourceRange());
+
+ // Decls
+ void VisitLabelDecl(LabelDecl *D);
+ void VisitTypedefDecl(TypedefDecl *D);
+ void VisitEnumDecl(EnumDecl *D);
+ void VisitRecordDecl(RecordDecl *D);
+ void VisitEnumConstantDecl(EnumConstantDecl *D);
+ void VisitIndirectFieldDecl(IndirectFieldDecl *D);
+ void VisitFunctionDecl(FunctionDecl *D);
+ void VisitFieldDecl(FieldDecl *D);
+ void VisitVarDecl(VarDecl *D);
+ void VisitFileScopeAsmDecl(FileScopeAsmDecl *D);
+ void VisitImportDecl(ImportDecl *D);
+
+ // C++ Decls
+ void VisitNamespaceDecl(NamespaceDecl *D);
+ void VisitUsingDirectiveDecl(UsingDirectiveDecl *D);
+ void VisitNamespaceAliasDecl(NamespaceAliasDecl *D);
+ void VisitTypeAliasDecl(TypeAliasDecl *D);
+ void VisitTypeAliasTemplateDecl(TypeAliasTemplateDecl *D);
+ void VisitCXXRecordDecl(CXXRecordDecl *D);
+ void VisitStaticAssertDecl(StaticAssertDecl *D);
+ void VisitFunctionTemplateDecl(FunctionTemplateDecl *D);
+ void VisitClassTemplateDecl(ClassTemplateDecl *D);
+ void VisitClassTemplateSpecializationDecl(
+ ClassTemplateSpecializationDecl *D);
+ void VisitClassTemplatePartialSpecializationDecl(
+ ClassTemplatePartialSpecializationDecl *D);
+ void VisitClassScopeFunctionSpecializationDecl(
+ ClassScopeFunctionSpecializationDecl *D);
+ void VisitTemplateTypeParmDecl(TemplateTypeParmDecl *D);
+ void VisitNonTypeTemplateParmDecl(NonTypeTemplateParmDecl *D);
+ void VisitTemplateTemplateParmDecl(TemplateTemplateParmDecl *D);
+ void VisitUsingDecl(UsingDecl *D);
+ void VisitUnresolvedUsingTypenameDecl(UnresolvedUsingTypenameDecl *D);
+ void VisitUnresolvedUsingValueDecl(UnresolvedUsingValueDecl *D);
+ void VisitUsingShadowDecl(UsingShadowDecl *D);
+ void VisitLinkageSpecDecl(LinkageSpecDecl *D);
+ void VisitAccessSpecDecl(AccessSpecDecl *D);
+ void VisitFriendDecl(FriendDecl *D);
+
+ // ObjC Decls
+ void VisitObjCIvarDecl(ObjCIvarDecl *D);
+ void VisitObjCMethodDecl(ObjCMethodDecl *D);
+ void VisitObjCCategoryDecl(ObjCCategoryDecl *D);
+ void VisitObjCCategoryImplDecl(ObjCCategoryImplDecl *D);
+ void VisitObjCProtocolDecl(ObjCProtocolDecl *D);
+ void VisitObjCInterfaceDecl(ObjCInterfaceDecl *D);
+ void VisitObjCImplementationDecl(ObjCImplementationDecl *D);
+ void VisitObjCCompatibleAliasDecl(ObjCCompatibleAliasDecl *D);
+ void VisitObjCPropertyDecl(ObjCPropertyDecl *D);
+ void VisitObjCPropertyImplDecl(ObjCPropertyImplDecl *D);
+ void VisitBlockDecl(BlockDecl *D);
// Stmts.
void VisitStmt(Stmt *Node);
@@ -137,6 +207,10 @@ void ASTDumper::unindent() {
IndentLevel--;
}
+void ASTDumper::dumpPointer(const void *Ptr) {
+ OS << ' ' << Ptr;
+}
+
void ASTDumper::dumpLocation(SourceLocation Loc) {
SourceLocation SpellingLoc = SM->getSpellingLoc(Loc);
@@ -163,15 +237,11 @@ void ASTDumper::dumpLocation(SourceLocation Loc) {
}
}
-void ASTDumper::dumpSourceRange(const Stmt *Node) {
+void ASTDumper::dumpSourceRange(SourceRange R) {
// Can't translate locations if a SourceManager isn't available.
if (!SM)
return;
- // TODO: If the parent expression is available, we can print a delta vs its
- // location.
- SourceRange R = Node->getSourceRange();
-
OS << " <";
dumpLocation(R.getBegin());
if (R.getBegin() != R.getEnd()) {
@@ -184,7 +254,7 @@ void ASTDumper::dumpSourceRange(const Stmt *Node) {
}
-void ASTDumper::dumpType(QualType T) {
+void ASTDumper::dumpBareType(QualType T) {
SplitQualType T_split = T.split();
OS << "'" << QualType::getAsString(T_split) << "'";
@@ -196,8 +266,14 @@ void ASTDumper::dumpType(QualType T) {
}
}
-void ASTDumper::dumpDeclRef(Decl *D) {
- OS << D->getDeclKindName() << ' ' << (void*) D;
+void ASTDumper::dumpType(QualType T) {
+ OS << ' ';
+ dumpBareType(T);
+}
+
+void ASTDumper::dumpBareDeclRef(Decl *D) {
+ OS << D->getDeclKindName();
+ dumpPointer(D);
if (NamedDecl *ND = dyn_cast<NamedDecl>(D)) {
OS << " '";
@@ -205,9 +281,132 @@ void ASTDumper::dumpDeclRef(Decl *D) {
OS << "'";
}
- if (ValueDecl *VD = dyn_cast<ValueDecl>(D)) {
- OS << ' ';
+ if (ValueDecl *VD = dyn_cast<ValueDecl>(D))
dumpType(VD->getType());
+}
+
+void ASTDumper::dumpDeclRef(Decl *D, const char *Label) {
+ if (!D)
+ return;
+
+ IndentScope Indent(*this);
+ if (Label)
+ OS << Label << ' ';
+ dumpBareDeclRef(D);
+}
+
+void ASTDumper::dumpName(NamedDecl *ND) {
+ if (ND->getDeclName())
+ OS << ' ' << ND->getNameAsString();
+}
+
+void ASTDumper::dumpDeclContext(DeclContext *DC) {
+ if (!DC)
+ return;
+ for (DeclContext::decl_iterator I = DC->decls_begin(), E = DC->decls_end();
+ I != E; ++I)
+ dumpDecl(*I);
+}
+
+//===----------------------------------------------------------------------===//
+// C++ Utilities
+//===----------------------------------------------------------------------===//
+
+void ASTDumper::dumpAccessSpecifier(AccessSpecifier AS) {
+ switch (AS) {
+ case AS_none:
+ break;
+ case AS_public:
+ OS << "public";
+ break;
+ case AS_protected:
+ OS << "protected";
+ break;
+ case AS_private:
+ OS << "private";
+ break;
+ }
+}
+
+void ASTDumper::dumpCXXCtorInitializer(CXXCtorInitializer *Init) {
+ IndentScope Indent(*this);
+ OS << "CXXCtorInitializer";
+ if (Init->isAnyMemberInitializer()) {
+ OS << ' ';
+ dumpBareDeclRef(Init->getAnyMember());
+ } else {
+ dumpType(QualType(Init->getBaseClass(), 0));
+ }
+ dumpStmt(Init->getInit());
+}
+
+void ASTDumper::dumpTemplateParameters(TemplateParameterList *TPL) {
+ if (!TPL)
+ return;
+
+ for (TemplateParameterList::iterator I = TPL->begin(), E = TPL->end();
+ I != E; ++I)
+ dumpDecl(*I);
+}
+
+void ASTDumper::dumpTemplateArgumentListInfo(
+ const TemplateArgumentListInfo &TALI) {
+ for (unsigned i = 0, e = TALI.size(); i < e; ++i)
+ dumpTemplateArgumentLoc(TALI[i]);
+}
+
+void ASTDumper::dumpTemplateArgumentLoc(const TemplateArgumentLoc &A) {
+ dumpTemplateArgument(A.getArgument(), A.getSourceRange());
+}
+
+void ASTDumper::dumpTemplateArgumentList(const TemplateArgumentList &TAL) {
+ for (unsigned i = 0, e = TAL.size(); i < e; ++i)
+ dumpTemplateArgument(TAL[i]);
+}
+
+void ASTDumper::dumpTemplateArgument(const TemplateArgument &A, SourceRange R) {
+ IndentScope Indent(*this);
+ OS << "TemplateArgument";
+ if (R.isValid())
+ dumpSourceRange(R);
+
+ switch (A.getKind()) {
+ case TemplateArgument::Null:
+ OS << " null";
+ break;
+ case TemplateArgument::Type:
+ OS << " type";
+ dumpType(A.getAsType());
+ break;
+ case TemplateArgument::Declaration:
+ OS << " decl";
+ dumpDeclRef(A.getAsDecl());
+ break;
+ case TemplateArgument::NullPtr:
+ OS << " nullptr";
+ break;
+ case TemplateArgument::Integral:
+ OS << " integral";
+ OS << ' ' << A.getAsIntegral();
+ break;
+ case TemplateArgument::Template:
+ OS << " template ";
+ A.getAsTemplate().dump(OS);
+ break;
+ case TemplateArgument::TemplateExpansion:
+ OS << " template expansion";
+ A.getAsTemplateOrTemplatePattern().dump(OS);
+ break;
+ case TemplateArgument::Expression:
+ OS << " expr";
+ dumpStmt(A.getAsExpr());
+ break;
+ case TemplateArgument::Pack:
+ OS << " pack";
+ for (TemplateArgument::pack_iterator I = A.pack_begin(), E = A.pack_end();
+ I != E; ++I)
+ dumpTemplateArgument(*I);
+ break;
}
}
@@ -216,71 +415,514 @@ void ASTDumper::dumpDeclRef(Decl *D) {
//===----------------------------------------------------------------------===//
void ASTDumper::dumpDecl(Decl *D) {
- // FIXME: Need to complete/beautify this... this code simply shows the
- // nodes are where they need to be.
- if (TypedefDecl *localType = dyn_cast<TypedefDecl>(D)) {
- OS << "\"typedef " << localType->getUnderlyingType().getAsString()
- << ' ' << *localType << '"';
- } else if (TypeAliasDecl *localType = dyn_cast<TypeAliasDecl>(D)) {
- OS << "\"using " << *localType << " = "
- << localType->getUnderlyingType().getAsString() << '"';
- } else if (ValueDecl *VD = dyn_cast<ValueDecl>(D)) {
- OS << "\"";
- // Emit storage class for vardecls.
- if (VarDecl *V = dyn_cast<VarDecl>(VD)) {
- if (V->getStorageClass() != SC_None)
- OS << VarDecl::getStorageClassSpecifierString(V->getStorageClass())
- << " ";
+ IndentScope Indent(*this);
+
+ if (!D) {
+ OS << "<<<NULL>>>";
+ return;
+ }
+
+ OS << D->getDeclKindName() << "Decl";
+ dumpPointer(D);
+ dumpSourceRange(D->getSourceRange());
+ DeclVisitor<ASTDumper>::Visit(D);
+ // Decls within functions are visited by the body
+ if (!isa<FunctionDecl>(*D) && !isa<ObjCMethodDecl>(*D))
+ dumpDeclContext(dyn_cast<DeclContext>(D));
+}
+
+void ASTDumper::VisitLabelDecl(LabelDecl *D) {
+ dumpName(D);
+}
+
+void ASTDumper::VisitTypedefDecl(TypedefDecl *D) {
+ dumpName(D);
+ dumpType(D->getUnderlyingType());
+ if (D->isModulePrivate())
+ OS << " __module_private__";
+}
+
+void ASTDumper::VisitEnumDecl(EnumDecl *D) {
+ if (D->isScoped()) {
+ if (D->isScopedUsingClassTag())
+ OS << " class";
+ else
+ OS << " struct";
+ }
+ dumpName(D);
+ if (D->isModulePrivate())
+ OS << " __module_private__";
+ if (D->isFixed())
+ dumpType(D->getIntegerType());
+}
+
+void ASTDumper::VisitRecordDecl(RecordDecl *D) {
+ OS << ' ' << D->getKindName();
+ dumpName(D);
+ if (D->isModulePrivate())
+ OS << " __module_private__";
+}
+
+void ASTDumper::VisitEnumConstantDecl(EnumConstantDecl *D) {
+ dumpName(D);
+ dumpType(D->getType());
+ if (Expr *Init = D->getInitExpr())
+ dumpStmt(Init);
+}
+
+void ASTDumper::VisitIndirectFieldDecl(IndirectFieldDecl *D) {
+ dumpName(D);
+ dumpType(D->getType());
+ for (IndirectFieldDecl::chain_iterator I = D->chain_begin(),
+ E = D->chain_end(); I != E; ++I)
+ dumpDeclRef(*I);
+}
+
+void ASTDumper::VisitFunctionDecl(FunctionDecl *D) {
+ dumpName(D);
+ dumpType(D->getType());
+
+ StorageClass SC = D->getStorageClassAsWritten();
+ if (SC != SC_None)
+ OS << ' ' << VarDecl::getStorageClassSpecifierString(SC);
+ if (D->isInlineSpecified())
+ OS << " inline";
+ if (D->isVirtualAsWritten())
+ OS << " virtual";
+ if (D->isModulePrivate())
+ OS << " __module_private__";
+
+ if (D->isPure())
+ OS << " pure";
+ else if (D->isDeletedAsWritten())
+ OS << " delete";
+
+ if (const FunctionTemplateSpecializationInfo *FTSI =
+ D->getTemplateSpecializationInfo())
+ dumpTemplateArgumentList(*FTSI->TemplateArguments);
+
+ for (llvm::ArrayRef<NamedDecl*>::iterator
+ I = D->getDeclsInPrototypeScope().begin(),
+ E = D->getDeclsInPrototypeScope().end(); I != E; ++I)
+ dumpDecl(*I);
+
+ for (FunctionDecl::param_iterator I = D->param_begin(), E = D->param_end();
+ I != E; ++I)
+ dumpDecl(*I);
+
+ if (CXXConstructorDecl *C = dyn_cast<CXXConstructorDecl>(D))
+ for (CXXConstructorDecl::init_const_iterator I = C->init_begin(),
+ E = C->init_end(); I != E; ++I)
+ dumpCXXCtorInitializer(*I);
+
+ if (D->doesThisDeclarationHaveABody())
+ dumpStmt(D->getBody());
+}
+
+void ASTDumper::VisitFieldDecl(FieldDecl *D) {
+ dumpName(D);
+ dumpType(D->getType());
+ if (D->isMutable())
+ OS << " mutable";
+ if (D->isModulePrivate())
+ OS << " __module_private__";
+ if (D->isBitField())
+ dumpStmt(D->getBitWidth());
+ if (Expr *Init = D->getInClassInitializer())
+ dumpStmt(Init);
+}
+
+void ASTDumper::VisitVarDecl(VarDecl *D) {
+ dumpName(D);
+ dumpType(D->getType());
+ StorageClass SC = D->getStorageClassAsWritten();
+ if (SC != SC_None)
+ OS << ' ' << VarDecl::getStorageClassSpecifierString(SC);
+ if (D->isThreadSpecified())
+ OS << " __thread";
+ if (D->isModulePrivate())
+ OS << " __module_private__";
+ if (D->isNRVOVariable())
+ OS << " nrvo";
+ if (D->hasInit())
+ dumpStmt(D->getInit());
+}
+
+void ASTDumper::VisitFileScopeAsmDecl(FileScopeAsmDecl *D) {
+ dumpStmt(D->getAsmString());
+}
+
+void ASTDumper::VisitImportDecl(ImportDecl *D) {
+ OS << ' ' << D->getImportedModule()->getFullModuleName();
+}
+
+//===----------------------------------------------------------------------===//
+// C++ Declarations
+//===----------------------------------------------------------------------===//
+
+void ASTDumper::VisitNamespaceDecl(NamespaceDecl *D) {
+ dumpName(D);
+ if (D->isInline())
+ OS << " inline";
+ if (!D->isOriginalNamespace())
+ dumpDeclRef(D->getOriginalNamespace(), "original");
+}
+
+void ASTDumper::VisitUsingDirectiveDecl(UsingDirectiveDecl *D) {
+ OS << ' ';
+ dumpBareDeclRef(D->getNominatedNamespace());
+}
+
+void ASTDumper::VisitNamespaceAliasDecl(NamespaceAliasDecl *D) {
+ dumpName(D);
+ dumpDeclRef(D->getAliasedNamespace());
+}
+
+void ASTDumper::VisitTypeAliasDecl(TypeAliasDecl *D) {
+ dumpName(D);
+ dumpType(D->getUnderlyingType());
+}
+
+void ASTDumper::VisitTypeAliasTemplateDecl(TypeAliasTemplateDecl *D) {
+ dumpName(D);
+ dumpTemplateParameters(D->getTemplateParameters());
+ dumpDecl(D->getTemplatedDecl());
+}
+
+void ASTDumper::VisitCXXRecordDecl(CXXRecordDecl *D) {
+ VisitRecordDecl(D);
+ if (!D->isCompleteDefinition())
+ return;
+
+ for (CXXRecordDecl::base_class_iterator I = D->bases_begin(),
+ E = D->bases_end(); I != E; ++I) {
+ IndentScope Indent(*this);
+ if (I->isVirtual())
+ OS << "virtual ";
+ dumpAccessSpecifier(I->getAccessSpecifier());
+ dumpType(I->getType());
+ if (I->isPackExpansion())
+ OS << "...";
+ }
+}
+
+void ASTDumper::VisitStaticAssertDecl(StaticAssertDecl *D) {
+ dumpStmt(D->getAssertExpr());
+ dumpStmt(D->getMessage());
+}
+
+void ASTDumper::VisitFunctionTemplateDecl(FunctionTemplateDecl *D) {
+ dumpName(D);
+ dumpTemplateParameters(D->getTemplateParameters());
+ dumpDecl(D->getTemplatedDecl());
+ for (FunctionTemplateDecl::spec_iterator I = D->spec_begin(),
+ E = D->spec_end(); I != E; ++I) {
+ switch (I->getTemplateSpecializationKind()) {
+ case TSK_Undeclared:
+ case TSK_ImplicitInstantiation:
+ case TSK_ExplicitInstantiationDeclaration:
+ case TSK_ExplicitInstantiationDefinition:
+ dumpDecl(*I);
+ break;
+ case TSK_ExplicitSpecialization:
+ dumpDeclRef(*I);
+ break;
+ }
+ }
+}
+
+void ASTDumper::VisitClassTemplateDecl(ClassTemplateDecl *D) {
+ dumpName(D);
+ dumpTemplateParameters(D->getTemplateParameters());
+ dumpDecl(D->getTemplatedDecl());
+ for (ClassTemplateDecl::spec_iterator I = D->spec_begin(), E = D->spec_end();
+ I != E; ++I) {
+ switch (I->getTemplateSpecializationKind()) {
+ case TSK_Undeclared:
+ case TSK_ImplicitInstantiation:
+ dumpDecl(*I);
+ break;
+ case TSK_ExplicitSpecialization:
+ case TSK_ExplicitInstantiationDeclaration:
+ case TSK_ExplicitInstantiationDefinition:
+ dumpDeclRef(*I);
+ break;
}
+ }
+}
- std::string Name = VD->getNameAsString();
- VD->getType().getAsStringInternal(Name,
- PrintingPolicy(VD->getASTContext().getLangOpts()));
- OS << Name;
+void ASTDumper::VisitClassTemplateSpecializationDecl(
+ ClassTemplateSpecializationDecl *D) {
+ VisitCXXRecordDecl(D);
+ dumpTemplateArgumentList(D->getTemplateArgs());
+}
- // If this is a vardecl with an initializer, emit it.
- if (VarDecl *V = dyn_cast<VarDecl>(VD)) {
- if (V->getInit()) {
- OS << " =";
- dumpStmt(V->getInit());
- }
+void ASTDumper::VisitClassTemplatePartialSpecializationDecl(
+ ClassTemplatePartialSpecializationDecl *D) {
+ VisitClassTemplateSpecializationDecl(D);
+ dumpTemplateParameters(D->getTemplateParameters());
+}
+
+void ASTDumper::VisitClassScopeFunctionSpecializationDecl(
+ ClassScopeFunctionSpecializationDecl *D) {
+ dumpDeclRef(D->getSpecialization());
+ if (D->hasExplicitTemplateArgs())
+ dumpTemplateArgumentListInfo(D->templateArgs());
+}
+
+void ASTDumper::VisitTemplateTypeParmDecl(TemplateTypeParmDecl *D) {
+ if (D->wasDeclaredWithTypename())
+ OS << " typename";
+ else
+ OS << " class";
+ if (D->isParameterPack())
+ OS << " ...";
+ dumpName(D);
+ if (D->hasDefaultArgument())
+ dumpType(D->getDefaultArgument());
+}
+
+void ASTDumper::VisitNonTypeTemplateParmDecl(NonTypeTemplateParmDecl *D) {
+ dumpType(D->getType());
+ if (D->isParameterPack())
+ OS << " ...";
+ dumpName(D);
+ if (D->hasDefaultArgument())
+ dumpStmt(D->getDefaultArgument());
+}
+
+void ASTDumper::VisitTemplateTemplateParmDecl(TemplateTemplateParmDecl *D) {
+ if (D->isParameterPack())
+ OS << " ...";
+ dumpName(D);
+ dumpTemplateParameters(D->getTemplateParameters());
+ if (D->hasDefaultArgument())
+ dumpTemplateArgumentLoc(D->getDefaultArgument());
+}
+
+void ASTDumper::VisitUsingDecl(UsingDecl *D) {
+ OS << ' ';
+ D->getQualifier()->print(OS, D->getASTContext().getPrintingPolicy());
+ OS << D->getNameAsString();
+}
+
+void
+ASTDumper::VisitUnresolvedUsingTypenameDecl(UnresolvedUsingTypenameDecl *D) {
+ OS << ' ';
+ D->getQualifier()->print(OS, D->getASTContext().getPrintingPolicy());
+ OS << D->getNameAsString();
+}
+
+void ASTDumper::VisitUnresolvedUsingValueDecl(UnresolvedUsingValueDecl *D) {
+ OS << ' ';
+ D->getQualifier()->print(OS, D->getASTContext().getPrintingPolicy());
+ OS << D->getNameAsString();
+ dumpType(D->getType());
+}
+
+void ASTDumper::VisitUsingShadowDecl(UsingShadowDecl *D) {
+ OS << ' ';
+ dumpBareDeclRef(D->getTargetDecl());
+}
+
+void ASTDumper::VisitLinkageSpecDecl(LinkageSpecDecl *D) {
+ switch (D->getLanguage()) {
+ case LinkageSpecDecl::lang_c: OS << " C"; break;
+ case LinkageSpecDecl::lang_cxx: OS << " C++"; break;
+ }
+}
+
+void ASTDumper::VisitAccessSpecDecl(AccessSpecDecl *D) {
+ OS << ' ';
+ dumpAccessSpecifier(D->getAccess());
+}
+
+void ASTDumper::VisitFriendDecl(FriendDecl *D) {
+ if (TypeSourceInfo *T = D->getFriendType())
+ dumpType(T->getType());
+ else
+ dumpDecl(D->getFriendDecl());
+}
+
+//===----------------------------------------------------------------------===//
+// Obj-C Declarations
+//===----------------------------------------------------------------------===//
+
+void ASTDumper::VisitObjCIvarDecl(ObjCIvarDecl *D) {
+ dumpName(D);
+ dumpType(D->getType());
+ if (D->getSynthesize())
+ OS << " synthesize";
+
+ switch (D->getAccessControl()) {
+ case ObjCIvarDecl::None:
+ OS << " none";
+ break;
+ case ObjCIvarDecl::Private:
+ OS << " private";
+ break;
+ case ObjCIvarDecl::Protected:
+ OS << " protected";
+ break;
+ case ObjCIvarDecl::Public:
+ OS << " public";
+ break;
+ case ObjCIvarDecl::Package:
+ OS << " package";
+ break;
+ }
+}
+
+void ASTDumper::VisitObjCMethodDecl(ObjCMethodDecl *D) {
+ if (D->isInstanceMethod())
+ OS << " -";
+ else
+ OS << " +";
+ dumpName(D);
+ dumpType(D->getResultType());
+
+ if (D->isThisDeclarationADefinition())
+ dumpDeclContext(D);
+ else {
+ for (ObjCMethodDecl::param_iterator I = D->param_begin(),
+ E = D->param_end(); I != E; ++I) {
+ dumpDecl(*I);
}
- OS << '"';
- } else if (TagDecl *TD = dyn_cast<TagDecl>(D)) {
- // print a free standing tag decl (e.g. "struct x;").
- const char *tagname;
- if (const IdentifierInfo *II = TD->getIdentifier())
- tagname = II->getNameStart();
- else
- tagname = "<anonymous>";
- OS << '"' << TD->getKindName() << ' ' << tagname << ";\"";
- // FIXME: print tag bodies.
- } else if (UsingDirectiveDecl *UD = dyn_cast<UsingDirectiveDecl>(D)) {
- // print using-directive decl (e.g. "using namespace x;")
- const char *ns;
- if (const IdentifierInfo *II = UD->getNominatedNamespace()->getIdentifier())
- ns = II->getNameStart();
- else
- ns = "<anonymous>";
- OS << '"' << UD->getDeclKindName() << ns << ";\"";
- } else if (UsingDecl *UD = dyn_cast<UsingDecl>(D)) {
- // print using decl (e.g. "using std::string;")
- const char *tn = UD->isTypeName() ? "typename " : "";
- OS << '"' << UD->getDeclKindName() << tn;
- UD->getQualifier()->print(OS,
- PrintingPolicy(UD->getASTContext().getLangOpts()));
- OS << ";\"";
- } else if (LabelDecl *LD = dyn_cast<LabelDecl>(D)) {
- OS << "label " << *LD;
- } else if (StaticAssertDecl *SAD = dyn_cast<StaticAssertDecl>(D)) {
- OS << "\"static_assert(";
- dumpStmt(SAD->getAssertExpr());
- OS << ",";
- dumpStmt(SAD->getMessage());
- OS << ");\"";
- } else {
- llvm_unreachable("Unexpected decl");
}
+
+ if (D->isVariadic()) {
+ IndentScope Indent(*this);
+ OS << "...";
+ }
+
+ if (D->hasBody())
+ dumpStmt(D->getBody());
+}
+
+void ASTDumper::VisitObjCCategoryDecl(ObjCCategoryDecl *D) {
+ dumpName(D);
+ dumpDeclRef(D->getClassInterface());
+ dumpDeclRef(D->getImplementation());
+ for (ObjCCategoryDecl::protocol_iterator I = D->protocol_begin(),
+ E = D->protocol_end(); I != E; ++I)
+ dumpDeclRef(*I);
+}
+
+void ASTDumper::VisitObjCCategoryImplDecl(ObjCCategoryImplDecl *D) {
+ dumpName(D);
+ dumpDeclRef(D->getClassInterface());
+ dumpDeclRef(D->getCategoryDecl());
+}
+
+void ASTDumper::VisitObjCProtocolDecl(ObjCProtocolDecl *D) {
+ dumpName(D);
+ for (ObjCProtocolDecl::protocol_iterator I = D->protocol_begin(),
+ E = D->protocol_end(); I != E; ++I)
+ dumpDeclRef(*I);
+}
+
+void ASTDumper::VisitObjCInterfaceDecl(ObjCInterfaceDecl *D) {
+ dumpName(D);
+ dumpDeclRef(D->getSuperClass(), "super");
+ dumpDeclRef(D->getImplementation());
+ for (ObjCInterfaceDecl::protocol_iterator I = D->protocol_begin(),
+ E = D->protocol_end(); I != E; ++I)
+ dumpDeclRef(*I);
+}
+
+void ASTDumper::VisitObjCImplementationDecl(ObjCImplementationDecl *D) {
+ dumpName(D);
+ dumpDeclRef(D->getSuperClass(), "super");
+ dumpDeclRef(D->getClassInterface());
+ for (ObjCImplementationDecl::init_iterator I = D->init_begin(),
+ E = D->init_end(); I != E; ++I)
+ dumpCXXCtorInitializer(*I);
+}
+
+void ASTDumper::VisitObjCCompatibleAliasDecl(ObjCCompatibleAliasDecl *D) {
+ dumpName(D);
+ dumpDeclRef(D->getClassInterface());
+}
+
+void ASTDumper::VisitObjCPropertyDecl(ObjCPropertyDecl *D) {
+ dumpName(D);
+ dumpType(D->getType());
+
+ if (D->getPropertyImplementation() == ObjCPropertyDecl::Required)
+ OS << " required";
+ else if (D->getPropertyImplementation() == ObjCPropertyDecl::Optional)
+ OS << " optional";
+
+ ObjCPropertyDecl::PropertyAttributeKind Attrs = D->getPropertyAttributes();
+ if (Attrs != ObjCPropertyDecl::OBJC_PR_noattr) {
+ if (Attrs & ObjCPropertyDecl::OBJC_PR_readonly)
+ OS << " readonly";
+ if (Attrs & ObjCPropertyDecl::OBJC_PR_assign)
+ OS << " assign";
+ if (Attrs & ObjCPropertyDecl::OBJC_PR_readwrite)
+ OS << " readwrite";
+ if (Attrs & ObjCPropertyDecl::OBJC_PR_retain)
+ OS << " retain";
+ if (Attrs & ObjCPropertyDecl::OBJC_PR_copy)
+ OS << " copy";
+ if (Attrs & ObjCPropertyDecl::OBJC_PR_nonatomic)
+ OS << " nonatomic";
+ if (Attrs & ObjCPropertyDecl::OBJC_PR_atomic)
+ OS << " atomic";
+ if (Attrs & ObjCPropertyDecl::OBJC_PR_weak)
+ OS << " weak";
+ if (Attrs & ObjCPropertyDecl::OBJC_PR_strong)
+ OS << " strong";
+ if (Attrs & ObjCPropertyDecl::OBJC_PR_unsafe_unretained)
+ OS << " unsafe_unretained";
+ if (Attrs & ObjCPropertyDecl::OBJC_PR_getter)
+ dumpDeclRef(D->getGetterMethodDecl(), "getter");
+ if (Attrs & ObjCPropertyDecl::OBJC_PR_setter)
+ dumpDeclRef(D->getSetterMethodDecl(), "setter");
+ }
+}
+
+void ASTDumper::VisitObjCPropertyImplDecl(ObjCPropertyImplDecl *D) {
+ dumpName(D->getPropertyDecl());
+ if (D->getPropertyImplementation() == ObjCPropertyImplDecl::Synthesize)
+ OS << " synthesize";
+ else
+ OS << " dynamic";
+ dumpDeclRef(D->getPropertyDecl());
+ dumpDeclRef(D->getPropertyIvarDecl());
+}
+
+void ASTDumper::VisitBlockDecl(BlockDecl *D) {
+ for (BlockDecl::param_iterator I = D->param_begin(), E = D->param_end();
+ I != E; ++I)
+ dumpDecl(*I);
+
+ if (D->isVariadic()) {
+ IndentScope Indent(*this);
+ OS << "...";
+ }
+
+ if (D->capturesCXXThis()) {
+ IndentScope Indent(*this);
+ OS << "capture this";
+ }
+ for (BlockDecl::capture_iterator I = D->capture_begin(),
+ E = D->capture_end(); I != E; ++I) {
+ IndentScope Indent(*this);
+ OS << "capture";
+ if (I->isByRef())
+ OS << " byref";
+ if (I->isNested())
+ OS << " nested";
+ if (I->getVariable()) {
+ OS << ' ';
+ dumpBareDeclRef(I->getVariable());
+ }
+ if (I->hasCopyExpr())
+ dumpStmt(I->getCopyExpr());
+ }
+
+ dumpStmt(D->getBody());
}
//===----------------------------------------------------------------------===//
@@ -300,25 +942,22 @@ void ASTDumper::dumpStmt(Stmt *S) {
return;
}
- Visit(S);
+ StmtVisitor<ASTDumper>::Visit(S);
for (Stmt::child_range CI = S->children(); CI; ++CI)
dumpStmt(*CI);
}
void ASTDumper::VisitStmt(Stmt *Node) {
- OS << Node->getStmtClassName() << " " << (const void *)Node;
- dumpSourceRange(Node);
+ OS << Node->getStmtClassName();
+ dumpPointer(Node);
+ dumpSourceRange(Node->getSourceRange());
}
void ASTDumper::VisitDeclStmt(DeclStmt *Node) {
VisitStmt(Node);
- for (DeclStmt::decl_iterator DI = Node->decl_begin(), DE = Node->decl_end();
- DI != DE; ++DI) {
- IndentScope Indent(*this);
- Decl *D = *DI;
- OS << (void*) D << " ";
- dumpDecl(D);
- }
+ for (DeclStmt::decl_iterator I = Node->decl_begin(), E = Node->decl_end();
+ I != E; ++I)
+ dumpDecl(*I);
}
void ASTDumper::VisitLabelStmt(LabelStmt *Node) {
@@ -328,8 +967,8 @@ void ASTDumper::VisitLabelStmt(LabelStmt *Node) {
void ASTDumper::VisitGotoStmt(GotoStmt *Node) {
VisitStmt(Node);
- OS << " '" << Node->getLabel()->getName()
- << "':" << (void*)Node->getLabel();
+ OS << " '" << Node->getLabel()->getName() << "'";
+ dumpPointer(Node->getLabel());
}
//===----------------------------------------------------------------------===//
@@ -338,7 +977,6 @@ void ASTDumper::VisitGotoStmt(GotoStmt *Node) {
void ASTDumper::VisitExpr(Expr *Node) {
VisitStmt(Node);
- OS << ' ';
dumpType(Node->getType());
switch (Node->getValueKind()) {
@@ -405,10 +1043,10 @@ void ASTDumper::VisitDeclRefExpr(DeclRefExpr *Node) {
VisitExpr(Node);
OS << " ";
- dumpDeclRef(Node->getDecl());
+ dumpBareDeclRef(Node->getDecl());
if (Node->getDecl() != Node->getFoundDecl()) {
OS << " (";
- dumpDeclRef(Node->getFoundDecl());
+ dumpBareDeclRef(Node->getFoundDecl());
OS << ")";
}
}
@@ -425,15 +1063,15 @@ void ASTDumper::VisitUnresolvedLookupExpr(UnresolvedLookupExpr *Node) {
if (I == E)
OS << " empty";
for (; I != E; ++I)
- OS << " " << (void*) *I;
+ dumpPointer(*I);
}
void ASTDumper::VisitObjCIvarRefExpr(ObjCIvarRefExpr *Node) {
VisitExpr(Node);
OS << " " << Node->getDecl()->getDeclKindName()
- << "Decl='" << *Node->getDecl()
- << "' " << (void*)Node->getDecl();
+ << "Decl='" << *Node->getDecl() << "'";
+ dumpPointer(Node->getDecl());
if (Node->isFreeIvar())
OS << " isFreeIvar";
}
@@ -482,13 +1120,13 @@ void ASTDumper::VisitUnaryExprOrTypeTraitExpr(UnaryExprOrTypeTraitExpr *Node) {
VisitExpr(Node);
switch(Node->getKind()) {
case UETT_SizeOf:
- OS << " sizeof ";
+ OS << " sizeof";
break;
case UETT_AlignOf:
- OS << " alignof ";
+ OS << " alignof";
break;
case UETT_VecStep:
- OS << " vec_step ";
+ OS << " vec_step";
break;
}
if (Node->isArgumentType())
@@ -497,9 +1135,8 @@ void ASTDumper::VisitUnaryExprOrTypeTraitExpr(UnaryExprOrTypeTraitExpr *Node) {
void ASTDumper::VisitMemberExpr(MemberExpr *Node) {
VisitExpr(Node);
- OS << " " << (Node->isArrow() ? "->" : ".")
- << *Node->getMemberDecl() << ' '
- << (void*)Node->getMemberDecl();
+ OS << " " << (Node->isArrow() ? "->" : ".") << *Node->getMemberDecl();
+ dumpPointer(Node->getMemberDecl());
}
void ASTDumper::VisitExtVectorElementExpr(ExtVectorElementExpr *Node) {
@@ -516,36 +1153,14 @@ void ASTDumper::VisitCompoundAssignOperator(CompoundAssignOperator *Node) {
VisitExpr(Node);
OS << " '" << BinaryOperator::getOpcodeStr(Node->getOpcode())
<< "' ComputeLHSTy=";
- dumpType(Node->getComputationLHSType());
+ dumpBareType(Node->getComputationLHSType());
OS << " ComputeResultTy=";
- dumpType(Node->getComputationResultType());
+ dumpBareType(Node->getComputationResultType());
}
void ASTDumper::VisitBlockExpr(BlockExpr *Node) {
VisitExpr(Node);
-
- BlockDecl *block = Node->getBlockDecl();
- OS << " decl=" << block;
-
- if (block->capturesCXXThis()) {
- IndentScope Indent(*this);
- OS << "capture this";
- }
- for (BlockDecl::capture_iterator
- i = block->capture_begin(), e = block->capture_end(); i != e; ++i) {
- IndentScope Indent(*this);
- OS << "capture ";
- if (i->isByRef())
- OS << "byref ";
- if (i->isNested())
- OS << "nested ";
- if (i->getVariable())
- dumpDeclRef(i->getVariable());
- if (i->hasCopyExpr())
- dumpStmt(i->getCopyExpr());
- }
-
- dumpStmt(block->getBody());
+ dumpDecl(Node->getBlockDecl());
}
void ASTDumper::VisitOpaqueValueExpr(OpaqueValueExpr *Node) {
@@ -559,8 +1174,8 @@ void ASTDumper::VisitOpaqueValueExpr(OpaqueValueExpr *Node) {
void ASTDumper::VisitAddrLabelExpr(AddrLabelExpr *Node) {
VisitExpr(Node);
- OS << " " << Node->getLabel()->getName()
- << " " << (void*)Node->getLabel();
+ OS << " " << Node->getLabel()->getName();
+ dumpPointer(Node->getLabel());
}
//===----------------------------------------------------------------------===//
@@ -610,15 +1225,14 @@ void ASTDumper::VisitCXXBindTemporaryExpr(CXXBindTemporaryExpr *Node) {
void ASTDumper::VisitExprWithCleanups(ExprWithCleanups *Node) {
VisitExpr(Node);
- for (unsigned i = 0, e = Node->getNumObjects(); i != e; ++i) {
- IndentScope Indent(*this);
- OS << "cleanup ";
- dumpDeclRef(Node->getObject(i));
- }
+ for (unsigned i = 0, e = Node->getNumObjects(); i != e; ++i)
+ dumpDeclRef(Node->getObject(i), "cleanup");
}
void ASTDumper::dumpCXXTemporary(CXXTemporary *Temporary) {
- OS << "(CXXTemporary " << (void *)Temporary << ")";
+ OS << "(CXXTemporary";
+ dumpPointer(Temporary);
+ OS << ")";
}
//===----------------------------------------------------------------------===//
@@ -634,7 +1248,7 @@ void ASTDumper::VisitObjCMessageExpr(ObjCMessageExpr *Node) {
case ObjCMessageExpr::Class:
OS << " class=";
- dumpType(Node->getClassReceiver());
+ dumpBareType(Node->getClassReceiver());
break;
case ObjCMessageExpr::SuperInstance:
@@ -654,17 +1268,14 @@ void ASTDumper::VisitObjCBoxedExpr(ObjCBoxedExpr *Node) {
void ASTDumper::VisitObjCAtCatchStmt(ObjCAtCatchStmt *Node) {
VisitStmt(Node);
- if (VarDecl *CatchParam = Node->getCatchParamDecl()) {
- OS << " catch parm = ";
+ if (VarDecl *CatchParam = Node->getCatchParamDecl())
dumpDecl(CatchParam);
- } else {
+ else
OS << " catch all";
- }
}
void ASTDumper::VisitObjCEncodeExpr(ObjCEncodeExpr *Node) {
VisitExpr(Node);
- OS << " ";
dumpType(Node->getEncodedType());
}
@@ -738,6 +1349,19 @@ void ASTDumper::VisitObjCBoolLiteralExpr(ObjCBoolLiteralExpr *Node) {
}
//===----------------------------------------------------------------------===//