}
};
+ 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)
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);
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) {
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;
}
}
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;
}
}
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;
}
}
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) {