Range-ify and simplify some of the AST dumping code by factoring out the lastChild check.

llvm-svn: 204086
This commit is contained in:
Richard Smith 2014-03-17 23:00:06 +00:00
parent f45faaf30d
commit dcc2c453a5
1 changed files with 75 additions and 81 deletions

View File

@ -149,6 +149,38 @@ namespace {
}
};
class ChildDumper {
ASTDumper &Dumper;
const Decl *Prev;
bool PrevRef;
public:
ChildDumper(ASTDumper &Dumper) : Dumper(Dumper), Prev(0) {}
~ChildDumper() {
if (Prev) {
Dumper.lastChild();
dump(0);
}
}
// FIXME: This should take an arbitrary callable as the dumping action.
void dump(const Decl *D, bool Ref = false) {
if (Prev) {
if (PrevRef)
Dumper.dumpDeclRef(Prev);
else
Dumper.dumpDecl(Prev);
}
Prev = D;
PrevRef = Ref;
}
void dumpRef(const Decl *D) { dump(D, true); }
// Give up ownership of the children of the node. By calling this,
// the caller takes back responsibility for calling lastChild().
void release() { dump(0); }
};
public:
ASTDumper(raw_ostream &OS, const CommandTraits *Traits,
const SourceManager *SM)
@ -511,17 +543,14 @@ bool ASTDumper::hasNodes(const DeclContext *DC) {
void ASTDumper::dumpDeclContext(const DeclContext *DC) {
if (!DC)
return;
bool HasUndeserializedDecls = DC->hasExternalLexicalStorage();
for (DeclContext::decl_iterator I = DC->noload_decls_begin(),
E = DC->noload_decls_end();
I != E; ++I) {
DeclContext::decl_iterator Next = I;
++Next;
if (Next == E && !HasUndeserializedDecls)
lastChild();
dumpDecl(*I);
}
if (HasUndeserializedDecls) {
ChildDumper Children(*this);
for (auto *D : DC->noload_decls())
Children.dump(D);
if (DC->hasExternalLexicalStorage()) {
Children.release();
lastChild();
IndentScope Indent(*this);
ColorScope Color(*this, UndeserializedColor);
@ -838,13 +867,10 @@ void ASTDumper::VisitEnumConstantDecl(const EnumConstantDecl *D) {
void ASTDumper::VisitIndirectFieldDecl(const IndirectFieldDecl *D) {
dumpName(D);
dumpType(D->getType());
for (IndirectFieldDecl::chain_iterator I = D->chain_begin(),
E = D->chain_end();
I != E; ++I) {
if (I + 1 == E)
lastChild();
dumpDeclRef(*I);
}
ChildDumper Children(*this);
for (auto *D : D->chain())
Children.dumpRef(D);
}
void ASTDumper::VisitFunctionDecl(const FunctionDecl *D) {
@ -1050,26 +1076,20 @@ void ASTDumper::VisitStaticAssertDecl(const StaticAssertDecl *D) {
void ASTDumper::VisitFunctionTemplateDecl(const 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) {
FunctionTemplateDecl::spec_iterator Next = I;
++Next;
if (Next == E)
lastChild();
switch (I->getTemplateSpecializationKind()) {
ChildDumper Children(*this);
Children.dump(D->getTemplatedDecl());
for (auto *Child : D->specializations()) {
switch (Child->getTemplateSpecializationKind()) {
case TSK_Undeclared:
case TSK_ImplicitInstantiation:
case TSK_ExplicitInstantiationDeclaration:
case TSK_ExplicitInstantiationDefinition:
if (D == D->getCanonicalDecl())
dumpDecl(*I);
else
dumpDeclRef(*I);
Children.dump(Child, /*Ref*/D != D->getCanonicalDecl());
break;
case TSK_ExplicitSpecialization:
dumpDeclRef(*I);
Children.dumpRef(Child);
break;
}
}
@ -1079,28 +1099,19 @@ void ASTDumper::VisitClassTemplateDecl(const ClassTemplateDecl *D) {
dumpName(D);
dumpTemplateParameters(D->getTemplateParameters());
ClassTemplateDecl::spec_iterator I = D->spec_begin();
ClassTemplateDecl::spec_iterator E = D->spec_end();
if (I == E)
lastChild();
dumpDecl(D->getTemplatedDecl());
for (; I != E; ++I) {
ClassTemplateDecl::spec_iterator Next = I;
++Next;
if (Next == E)
lastChild();
switch (I->getTemplateSpecializationKind()) {
ChildDumper Children(*this);
Children.dump(D->getTemplatedDecl());
for (auto *Child : D->specializations()) {
switch (Child->getTemplateSpecializationKind()) {
case TSK_Undeclared:
case TSK_ImplicitInstantiation:
if (D == D->getCanonicalDecl())
dumpDecl(*I);
else
dumpDeclRef(*I);
Children.dump(Child, D != D->getCanonicalDecl());
break;
case TSK_ExplicitSpecialization:
case TSK_ExplicitInstantiationDeclaration:
case TSK_ExplicitInstantiationDefinition:
dumpDeclRef(*I);
Children.dumpRef(Child);
break;
}
}
@ -1129,28 +1140,19 @@ void ASTDumper::VisitVarTemplateDecl(const VarTemplateDecl *D) {
dumpName(D);
dumpTemplateParameters(D->getTemplateParameters());
VarTemplateDecl::spec_iterator I = D->spec_begin();
VarTemplateDecl::spec_iterator E = D->spec_end();
if (I == E)
lastChild();
dumpDecl(D->getTemplatedDecl());
for (; I != E; ++I) {
VarTemplateDecl::spec_iterator Next = I;
++Next;
if (Next == E)
lastChild();
switch (I->getTemplateSpecializationKind()) {
ChildDumper Children(*this);
Children.dump(D->getTemplatedDecl());
for (auto *Child : D->specializations()) {
switch (Child->getTemplateSpecializationKind()) {
case TSK_Undeclared:
case TSK_ImplicitInstantiation:
if (D == D->getCanonicalDecl())
dumpDecl(*I);
else
dumpDeclRef(*I);
Children.dump(Child, D != D->getCanonicalDecl());
break;
case TSK_ExplicitSpecialization:
case TSK_ExplicitInstantiationDeclaration:
case TSK_ExplicitInstantiationDefinition:
dumpDeclRef(*I);
Children.dumpRef(Child);
break;
}
}
@ -1337,28 +1339,20 @@ void ASTDumper::VisitObjCCategoryImplDecl(const ObjCCategoryImplDecl *D) {
void ASTDumper::VisitObjCProtocolDecl(const ObjCProtocolDecl *D) {
dumpName(D);
for (ObjCProtocolDecl::protocol_iterator I = D->protocol_begin(),
E = D->protocol_end();
I != E; ++I) {
if (I + 1 == E)
lastChild();
dumpDeclRef(*I);
}
ChildDumper Children(*this);
for (auto *D : D->protocols())
Children.dumpRef(D);
}
void ASTDumper::VisitObjCInterfaceDecl(const ObjCInterfaceDecl *D) {
dumpName(D);
dumpDeclRef(D->getSuperClass(), "super");
if (D->protocol_begin() == D->protocol_end())
lastChild();
dumpDeclRef(D->getImplementation());
for (ObjCInterfaceDecl::protocol_iterator I = D->protocol_begin(),
E = D->protocol_end();
I != E; ++I) {
if (I + 1 == E)
lastChild();
dumpDeclRef(*I);
}
ChildDumper Children(*this);
Children.dumpRef(D->getImplementation());
for (auto *D : D->protocols())
Children.dumpRef(D);
}
void ASTDumper::VisitObjCImplementationDecl(const ObjCImplementationDecl *D) {