forked from OSchip/llvm-project
Range-ify and simplify some of the AST dumping code by factoring out the lastChild check.
llvm-svn: 204086
This commit is contained in:
parent
f45faaf30d
commit
dcc2c453a5
|
@ -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) {
|
||||
|
|
Loading…
Reference in New Issue