123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029 |
- //===--- DumpXML.cpp - Detailed XML dumping ---------------------*- C++ -*-===//
- //
- // The LLVM Compiler Infrastructure
- //
- // This file is distributed under the University of Illinois Open Source
- // License. See LICENSE.TXT for details.
- //
- //===----------------------------------------------------------------------===//
- //
- // This file defines the Decl::dumpXML() method, a debugging tool to
- // print a detailed graph of an AST in an unspecified XML format.
- //
- // There is no guarantee of stability for this format.
- //
- //===----------------------------------------------------------------------===//
- // Only pay for this in code size in assertions-enabled builds.
- #include "clang/AST/ASTContext.h"
- #include "clang/AST/Decl.h"
- #include "clang/AST/DeclCXX.h"
- #include "clang/AST/DeclFriend.h"
- #include "clang/AST/DeclObjC.h"
- #include "clang/AST/DeclTemplate.h"
- #include "clang/AST/DeclVisitor.h"
- #include "clang/AST/Expr.h"
- #include "clang/AST/ExprCXX.h"
- #include "clang/AST/ExprObjC.h"
- #include "clang/AST/NestedNameSpecifier.h"
- #include "clang/AST/Stmt.h"
- #include "clang/AST/StmtCXX.h"
- #include "clang/AST/StmtObjC.h"
- #include "clang/AST/StmtVisitor.h"
- #include "clang/AST/TemplateBase.h"
- #include "clang/AST/TemplateName.h"
- #include "clang/AST/Type.h"
- #include "clang/AST/TypeLoc.h"
- #include "clang/AST/TypeLocVisitor.h"
- #include "clang/AST/TypeVisitor.h"
- #include "clang/AST/Expr.h"
- #include "clang/AST/ExprCXX.h"
- #include "llvm/ADT/SmallString.h"
- using namespace clang;
- #ifndef NDEBUG
- namespace {
- enum NodeState {
- NS_Attrs, NS_LazyChildren, NS_Children
- };
- struct Node {
- StringRef Name;
- NodeState State;
- Node(StringRef name) : Name(name), State(NS_Attrs) {}
- bool isDoneWithAttrs() const { return State != NS_Attrs; }
- };
- template <class Impl> struct XMLDeclVisitor {
- #define DISPATCH(NAME, CLASS) \
- static_cast<Impl*>(this)->NAME(static_cast<CLASS*>(D))
- void dispatch(Decl *D) {
- switch (D->getKind()) {
- #define DECL(DERIVED, BASE) \
- case Decl::DERIVED: \
- DISPATCH(dispatch##DERIVED##DeclAttrs, DERIVED##Decl); \
- static_cast<Impl*>(this)->completeAttrs(); \
- DISPATCH(dispatch##DERIVED##DeclChildren, DERIVED##Decl); \
- DISPATCH(dispatch##DERIVED##DeclAsContext, DERIVED##Decl); \
- break;
- #define ABSTRACT_DECL(DECL)
- #include "clang/AST/DeclNodes.inc"
- }
- }
- #define DECL(DERIVED, BASE) \
- void dispatch##DERIVED##DeclAttrs(DERIVED##Decl *D) { \
- DISPATCH(dispatch##BASE##Attrs, BASE); \
- DISPATCH(visit##DERIVED##DeclAttrs, DERIVED##Decl); \
- } \
- void visit##DERIVED##DeclAttrs(DERIVED##Decl *D) {} \
- void dispatch##DERIVED##DeclChildren(DERIVED##Decl *D) { \
- DISPATCH(dispatch##BASE##Children, BASE); \
- DISPATCH(visit##DERIVED##DeclChildren, DERIVED##Decl); \
- } \
- void visit##DERIVED##DeclChildren(DERIVED##Decl *D) {} \
- void dispatch##DERIVED##DeclAsContext(DERIVED##Decl *D) { \
- DISPATCH(dispatch##BASE##AsContext, BASE); \
- DISPATCH(visit##DERIVED##DeclAsContext, DERIVED##Decl); \
- } \
- void visit##DERIVED##DeclAsContext(DERIVED##Decl *D) {}
- #include "clang/AST/DeclNodes.inc"
- void dispatchDeclAttrs(Decl *D) {
- DISPATCH(visitDeclAttrs, Decl);
- }
- void visitDeclAttrs(Decl *D) {}
- void dispatchDeclChildren(Decl *D) {
- DISPATCH(visitDeclChildren, Decl);
- }
- void visitDeclChildren(Decl *D) {}
- void dispatchDeclAsContext(Decl *D) {
- DISPATCH(visitDeclAsContext, Decl);
- }
- void visitDeclAsContext(Decl *D) {}
- #undef DISPATCH
- };
- template <class Impl> struct XMLTypeVisitor {
- #define DISPATCH(NAME, CLASS) \
- static_cast<Impl*>(this)->NAME(static_cast<CLASS*>(T))
- void dispatch(Type *T) {
- switch (T->getTypeClass()) {
- #define TYPE(DERIVED, BASE) \
- case Type::DERIVED: \
- DISPATCH(dispatch##DERIVED##TypeAttrs, DERIVED##Type); \
- static_cast<Impl*>(this)->completeAttrs(); \
- DISPATCH(dispatch##DERIVED##TypeChildren, DERIVED##Type); \
- break;
- #define ABSTRACT_TYPE(DERIVED, BASE)
- #include "clang/AST/TypeNodes.def"
- }
- }
- #define TYPE(DERIVED, BASE) \
- void dispatch##DERIVED##TypeAttrs(DERIVED##Type *T) { \
- DISPATCH(dispatch##BASE##Attrs, BASE); \
- DISPATCH(visit##DERIVED##TypeAttrs, DERIVED##Type); \
- } \
- void visit##DERIVED##TypeAttrs(DERIVED##Type *T) {} \
- void dispatch##DERIVED##TypeChildren(DERIVED##Type *T) { \
- DISPATCH(dispatch##BASE##Children, BASE); \
- DISPATCH(visit##DERIVED##TypeChildren, DERIVED##Type); \
- } \
- void visit##DERIVED##TypeChildren(DERIVED##Type *T) {}
- #include "clang/AST/TypeNodes.def"
- void dispatchTypeAttrs(Type *T) {
- DISPATCH(visitTypeAttrs, Type);
- }
- void visitTypeAttrs(Type *T) {}
- void dispatchTypeChildren(Type *T) {
- DISPATCH(visitTypeChildren, Type);
- }
- void visitTypeChildren(Type *T) {}
- #undef DISPATCH
- };
- static StringRef getTypeKindName(Type *T) {
- switch (T->getTypeClass()) {
- #define TYPE(DERIVED, BASE) case Type::DERIVED: return #DERIVED "Type";
- #define ABSTRACT_TYPE(DERIVED, BASE)
- #include "clang/AST/TypeNodes.def"
- }
- llvm_unreachable("unknown type kind!");
- }
- struct XMLDumper : public XMLDeclVisitor<XMLDumper>,
- public XMLTypeVisitor<XMLDumper> {
- raw_ostream &out;
- ASTContext &Context;
- SmallVector<Node, 16> Stack;
- unsigned Indent;
- explicit XMLDumper(raw_ostream &OS, ASTContext &context)
- : out(OS), Context(context), Indent(0) {}
- void indent() {
- for (unsigned I = Indent; I; --I)
- out << ' ';
- }
- /// Push a new node on the stack.
- void push(StringRef name) {
- if (!Stack.empty()) {
- assert(Stack.back().isDoneWithAttrs());
- if (Stack.back().State == NS_LazyChildren) {
- Stack.back().State = NS_Children;
- out << ">\n";
- }
- Indent++;
- indent();
- }
- Stack.push_back(Node(name));
- out << '<' << name;
- }
- /// Set the given attribute to the given value.
- void set(StringRef attr, StringRef value) {
- assert(!Stack.empty() && !Stack.back().isDoneWithAttrs());
- out << ' ' << attr << '=' << '"' << value << '"'; // TODO: quotation
- }
- /// Finish attributes.
- void completeAttrs() {
- assert(!Stack.empty() && !Stack.back().isDoneWithAttrs());
- Stack.back().State = NS_LazyChildren;
- }
- /// Pop a node.
- void pop() {
- assert(!Stack.empty() && Stack.back().isDoneWithAttrs());
- if (Stack.back().State == NS_LazyChildren) {
- out << "/>\n";
- } else {
- indent();
- out << "</" << Stack.back().Name << ">\n";
- }
- if (Stack.size() > 1) Indent--;
- Stack.pop_back();
- }
- //---- General utilities -------------------------------------------//
- void setPointer(StringRef prop, const void *p) {
- SmallString<10> buffer;
- llvm::raw_svector_ostream os(buffer);
- os << p;
- os.flush();
- set(prop, buffer);
- }
- void setPointer(void *p) {
- setPointer("ptr", p);
- }
- void setInteger(StringRef prop, const llvm::APSInt &v) {
- set(prop, v.toString(10));
- }
- void setInteger(StringRef prop, unsigned n) {
- SmallString<10> buffer;
- llvm::raw_svector_ostream os(buffer);
- os << n;
- os.flush();
- set(prop, buffer);
- }
- void setFlag(StringRef prop, bool flag) {
- if (flag) set(prop, "true");
- }
- void setName(DeclarationName Name) {
- if (!Name)
- return set("name", "");
- // Common case.
- if (Name.isIdentifier())
- return set("name", Name.getAsIdentifierInfo()->getName());
- set("name", Name.getAsString());
- }
- class TemporaryContainer {
- XMLDumper &Dumper;
- public:
- TemporaryContainer(XMLDumper &dumper, StringRef name)
- : Dumper(dumper) {
- Dumper.push(name);
- Dumper.completeAttrs();
- }
- ~TemporaryContainer() {
- Dumper.pop();
- }
- };
- void visitTemplateParameters(TemplateParameterList *L) {
- push("template_parameters");
- completeAttrs();
- for (TemplateParameterList::iterator
- I = L->begin(), E = L->end(); I != E; ++I)
- dispatch(*I);
- pop();
- }
- void visitTemplateArguments(const TemplateArgumentList &L) {
- push("template_arguments");
- completeAttrs();
- for (unsigned I = 0, E = L.size(); I != E; ++I)
- dispatch(L[I]);
- pop();
- }
- /// Visits a reference to the given declaration.
- void visitDeclRef(Decl *D) {
- push(D->getDeclKindName());
- setPointer("ref", D);
- completeAttrs();
- pop();
- }
- void visitDeclRef(StringRef Name, Decl *D) {
- TemporaryContainer C(*this, Name);
- if (D) visitDeclRef(D);
- }
- void dispatch(const TemplateArgument &A) {
- switch (A.getKind()) {
- case TemplateArgument::Null: {
- TemporaryContainer C(*this, "null");
- break;
- }
- case TemplateArgument::Type: {
- dispatch(A.getAsType());
- break;
- }
- case TemplateArgument::Template:
- case TemplateArgument::TemplateExpansion:
- // FIXME: Implement!
- break;
-
- case TemplateArgument::Declaration: {
- visitDeclRef(A.getAsDecl());
- break;
- }
- case TemplateArgument::Integral: {
- push("integer");
- setInteger("value", *A.getAsIntegral());
- completeAttrs();
- pop();
- break;
- }
- case TemplateArgument::Expression: {
- dispatch(A.getAsExpr());
- break;
- }
- case TemplateArgument::Pack: {
- for (TemplateArgument::pack_iterator P = A.pack_begin(),
- PEnd = A.pack_end();
- P != PEnd; ++P)
- dispatch(*P);
- break;
- }
- }
- }
- void dispatch(const TemplateArgumentLoc &A) {
- dispatch(A.getArgument());
- }
- //---- Declarations ------------------------------------------------//
- // Calls are made in this order:
- // # Enter a new node.
- // push("FieldDecl")
- //
- // # In this phase, attributes are set on the node.
- // visitDeclAttrs(D)
- // visitNamedDeclAttrs(D)
- // ...
- // visitFieldDeclAttrs(D)
- //
- // # No more attributes after this point.
- // completeAttrs()
- //
- // # Create "header" child nodes, i.e. those which logically
- // # belong to the declaration itself.
- // visitDeclChildren(D)
- // visitNamedDeclChildren(D)
- // ...
- // visitFieldDeclChildren(D)
- //
- // # Create nodes for the lexical children.
- // visitDeclAsContext(D)
- // visitNamedDeclAsContext(D)
- // ...
- // visitFieldDeclAsContext(D)
- //
- // # Finish the node.
- // pop();
- void dispatch(Decl *D) {
- push(D->getDeclKindName());
- XMLDeclVisitor<XMLDumper>::dispatch(D);
- pop();
- }
- void visitDeclAttrs(Decl *D) {
- setPointer(D);
- }
- /// Visit all the lexical decls in the given context.
- void visitDeclContext(DeclContext *DC) {
- for (DeclContext::decl_iterator
- I = DC->decls_begin(), E = DC->decls_end(); I != E; ++I)
- dispatch(*I);
- // FIXME: point out visible declarations not in lexical context?
- }
- /// Set the "access" attribute on the current node according to the
- /// given specifier.
- void setAccess(AccessSpecifier AS) {
- switch (AS) {
- case AS_public: return set("access", "public");
- case AS_protected: return set("access", "protected");
- case AS_private: return set("access", "private");
- case AS_none: llvm_unreachable("explicit forbidden access");
- }
- }
- template <class T> void visitRedeclarableAttrs(T *D) {
- if (T *Prev = D->getPreviousDecl())
- setPointer("previous", Prev);
- }
- // TranslationUnitDecl
- void visitTranslationUnitDeclAsContext(TranslationUnitDecl *D) {
- visitDeclContext(D);
- }
- // LinkageSpecDecl
- void visitLinkageSpecDeclAttrs(LinkageSpecDecl *D) {
- StringRef lang = "";
- switch (D->getLanguage()) {
- case LinkageSpecDecl::lang_c: lang = "C"; break;
- case LinkageSpecDecl::lang_cxx: lang = "C++"; break;
- }
- set("lang", lang);
- }
- void visitLinkageSpecDeclAsContext(LinkageSpecDecl *D) {
- visitDeclContext(D);
- }
- // NamespaceDecl
- void visitNamespaceDeclAttrs(NamespaceDecl *D) {
- setFlag("inline", D->isInline());
- if (!D->isOriginalNamespace())
- setPointer("original", D->getOriginalNamespace());
- }
- void visitNamespaceDeclAsContext(NamespaceDecl *D) {
- visitDeclContext(D);
- }
- // NamedDecl
- void visitNamedDeclAttrs(NamedDecl *D) {
- setName(D->getDeclName());
- }
- // ValueDecl
- void visitValueDeclChildren(ValueDecl *D) {
- dispatch(D->getType());
- }
- // DeclaratorDecl
- void visitDeclaratorDeclChildren(DeclaratorDecl *D) {
- //dispatch(D->getTypeSourceInfo()->getTypeLoc());
- }
- // VarDecl
- void visitVarDeclAttrs(VarDecl *D) {
- visitRedeclarableAttrs(D);
- if (D->getStorageClass() != SC_None)
- set("storage",
- VarDecl::getStorageClassSpecifierString(D->getStorageClass()));
- setFlag("directinit", D->hasCXXDirectInitializer());
- setFlag("nrvo", D->isNRVOVariable());
- // TODO: instantiation, etc.
- }
- void visitVarDeclChildren(VarDecl *D) {
- if (D->hasInit()) dispatch(D->getInit());
- }
- // ParmVarDecl?
- // FunctionDecl
- void visitFunctionDeclAttrs(FunctionDecl *D) {
- visitRedeclarableAttrs(D);
- setFlag("pure", D->isPure());
- setFlag("trivial", D->isTrivial());
- setFlag("returnzero", D->hasImplicitReturnZero());
- setFlag("prototype", D->hasWrittenPrototype());
- setFlag("deleted", D->isDeletedAsWritten());
- if (D->getStorageClass() != SC_None)
- set("storage",
- VarDecl::getStorageClassSpecifierString(D->getStorageClass()));
- setFlag("inline", D->isInlineSpecified());
- if (const AsmLabelAttr *ALA = D->getAttr<AsmLabelAttr>())
- set("asmlabel", ALA->getLabel());
- // TODO: instantiation, etc.
- }
- void visitFunctionDeclChildren(FunctionDecl *D) {
- for (FunctionDecl::param_iterator
- I = D->param_begin(), E = D->param_end(); I != E; ++I)
- dispatch(*I);
- if (D->doesThisDeclarationHaveABody())
- dispatch(D->getBody());
- }
- // CXXMethodDecl ?
- // CXXConstructorDecl ?
- // CXXDestructorDecl ?
- // CXXConversionDecl ?
- void dispatch(CXXCtorInitializer *Init) {
- // TODO
- }
- // FieldDecl
- void visitFieldDeclAttrs(FieldDecl *D) {
- setFlag("mutable", D->isMutable());
- }
- void visitFieldDeclChildren(FieldDecl *D) {
- if (D->isBitField()) {
- TemporaryContainer C(*this, "bitwidth");
- dispatch(D->getBitWidth());
- }
- // TODO: C++0x member initializer
- }
- // EnumConstantDecl
- void visitEnumConstantDeclChildren(EnumConstantDecl *D) {
- // value in any case?
- if (D->getInitExpr()) dispatch(D->getInitExpr());
- }
- // IndirectFieldDecl
- void visitIndirectFieldDeclChildren(IndirectFieldDecl *D) {
- for (IndirectFieldDecl::chain_iterator
- I = D->chain_begin(), E = D->chain_end(); I != E; ++I) {
- NamedDecl *VD = const_cast<NamedDecl*>(*I);
- push(isa<VarDecl>(VD) ? "variable" : "field");
- setPointer("ptr", VD);
- completeAttrs();
- pop();
- }
- }
- // TypeDecl
- void visitTypeDeclAttrs(TypeDecl *D) {
- setPointer("typeptr", D->getTypeForDecl());
- }
- // TypedefDecl
- void visitTypedefDeclAttrs(TypedefDecl *D) {
- visitRedeclarableAttrs<TypedefNameDecl>(D);
- }
- void visitTypedefDeclChildren(TypedefDecl *D) {
- dispatch(D->getTypeSourceInfo()->getTypeLoc());
- }
- // TypeAliasDecl
- void visitTypeAliasDeclAttrs(TypeAliasDecl *D) {
- visitRedeclarableAttrs<TypedefNameDecl>(D);
- }
- void visitTypeAliasDeclChildren(TypeAliasDecl *D) {
- dispatch(D->getTypeSourceInfo()->getTypeLoc());
- }
- // TagDecl
- void visitTagDeclAttrs(TagDecl *D) {
- visitRedeclarableAttrs(D);
- }
- void visitTagDeclAsContext(TagDecl *D) {
- visitDeclContext(D);
- }
- // EnumDecl
- void visitEnumDeclAttrs(EnumDecl *D) {
- setFlag("scoped", D->isScoped());
- setFlag("fixed", D->isFixed());
- }
- void visitEnumDeclChildren(EnumDecl *D) {
- {
- TemporaryContainer C(*this, "promotion_type");
- dispatch(D->getPromotionType());
- }
- {
- TemporaryContainer C(*this, "integer_type");
- dispatch(D->getIntegerType());
- }
- }
- // RecordDecl ?
- void visitCXXRecordDeclChildren(CXXRecordDecl *D) {
- if (!D->isThisDeclarationADefinition()) return;
- for (CXXRecordDecl::base_class_iterator
- I = D->bases_begin(), E = D->bases_end(); I != E; ++I) {
- push("base");
- setAccess(I->getAccessSpecifier());
- completeAttrs();
- dispatch(I->getTypeSourceInfo()->getTypeLoc());
- pop();
- }
- }
- // ClassTemplateSpecializationDecl ?
- // FileScopeAsmDecl ?
- // BlockDecl
- void visitBlockDeclAttrs(BlockDecl *D) {
- setFlag("variadic", D->isVariadic());
- }
- void visitBlockDeclChildren(BlockDecl *D) {
- for (FunctionDecl::param_iterator
- I = D->param_begin(), E = D->param_end(); I != E; ++I)
- dispatch(*I);
- dispatch(D->getBody());
- }
- // AccessSpecDecl
- void visitAccessSpecDeclAttrs(AccessSpecDecl *D) {
- setAccess(D->getAccess());
- }
- // TemplateDecl
- void visitTemplateDeclChildren(TemplateDecl *D) {
- visitTemplateParameters(D->getTemplateParameters());
- if (D->getTemplatedDecl())
- dispatch(D->getTemplatedDecl());
- }
- // FunctionTemplateDecl
- void visitFunctionTemplateDeclAttrs(FunctionTemplateDecl *D) {
- visitRedeclarableAttrs(D);
- }
- void visitFunctionTemplateDeclChildren(FunctionTemplateDecl *D) {
- // Mention all the specializations which don't have explicit
- // declarations elsewhere.
- for (FunctionTemplateDecl::spec_iterator
- I = D->spec_begin(), E = D->spec_end(); I != E; ++I) {
- FunctionTemplateSpecializationInfo *Info
- = I->getTemplateSpecializationInfo();
- bool Unknown = false;
- switch (Info->getTemplateSpecializationKind()) {
- case TSK_ImplicitInstantiation: Unknown = false; break;
- case TSK_Undeclared: Unknown = true; break;
- // These will be covered at their respective sites.
- case TSK_ExplicitSpecialization: continue;
- case TSK_ExplicitInstantiationDeclaration: continue;
- case TSK_ExplicitInstantiationDefinition: continue;
- }
- TemporaryContainer C(*this,
- Unknown ? "uninstantiated" : "instantiation");
- visitTemplateArguments(*Info->TemplateArguments);
- dispatch(Info->Function);
- }
- }
- // ClasTemplateDecl
- void visitClassTemplateDeclAttrs(ClassTemplateDecl *D) {
- visitRedeclarableAttrs(D);
- }
- void visitClassTemplateDeclChildren(ClassTemplateDecl *D) {
- // Mention all the specializations which don't have explicit
- // declarations elsewhere.
- for (ClassTemplateDecl::spec_iterator
- I = D->spec_begin(), E = D->spec_end(); I != E; ++I) {
- bool Unknown = false;
- switch (I->getTemplateSpecializationKind()) {
- case TSK_ImplicitInstantiation: Unknown = false; break;
- case TSK_Undeclared: Unknown = true; break;
- // These will be covered at their respective sites.
- case TSK_ExplicitSpecialization: continue;
- case TSK_ExplicitInstantiationDeclaration: continue;
- case TSK_ExplicitInstantiationDefinition: continue;
- }
- TemporaryContainer C(*this,
- Unknown ? "uninstantiated" : "instantiation");
- visitTemplateArguments(I->getTemplateArgs());
- dispatch(*I);
- }
- }
- // TemplateTypeParmDecl
- void visitTemplateTypeParmDeclAttrs(TemplateTypeParmDecl *D) {
- setInteger("depth", D->getDepth());
- setInteger("index", D->getIndex());
- }
- void visitTemplateTypeParmDeclChildren(TemplateTypeParmDecl *D) {
- if (D->hasDefaultArgument() && !D->defaultArgumentWasInherited())
- dispatch(D->getDefaultArgumentInfo()->getTypeLoc());
- // parameter pack?
- }
- // NonTypeTemplateParmDecl
- void visitNonTypeTemplateParmDeclAttrs(NonTypeTemplateParmDecl *D) {
- setInteger("depth", D->getDepth());
- setInteger("index", D->getIndex());
- }
- void visitNonTypeTemplateParmDeclChildren(NonTypeTemplateParmDecl *D) {
- if (D->hasDefaultArgument() && !D->defaultArgumentWasInherited())
- dispatch(D->getDefaultArgument());
- // parameter pack?
- }
- // TemplateTemplateParmDecl
- void visitTemplateTemplateParmDeclAttrs(TemplateTemplateParmDecl *D) {
- setInteger("depth", D->getDepth());
- setInteger("index", D->getIndex());
- }
- void visitTemplateTemplateParmDeclChildren(TemplateTemplateParmDecl *D) {
- if (D->hasDefaultArgument() && !D->defaultArgumentWasInherited())
- dispatch(D->getDefaultArgument());
- // parameter pack?
- }
- // FriendDecl
- void visitFriendDeclChildren(FriendDecl *D) {
- if (TypeSourceInfo *T = D->getFriendType())
- dispatch(T->getTypeLoc());
- else
- dispatch(D->getFriendDecl());
- }
- // UsingDirectiveDecl ?
- // UsingDecl ?
- // UsingShadowDecl ?
- // NamespaceAliasDecl ?
- // UnresolvedUsingValueDecl ?
- // UnresolvedUsingTypenameDecl ?
- // StaticAssertDecl ?
- // ObjCImplDecl
- void visitObjCImplDeclChildren(ObjCImplDecl *D) {
- visitDeclRef(D->getClassInterface());
- }
- void visitObjCImplDeclAsContext(ObjCImplDecl *D) {
- visitDeclContext(D);
- }
- // ObjCInterfaceDecl
- void visitCategoryList(ObjCCategoryDecl *D) {
- if (!D) return;
- TemporaryContainer C(*this, "categories");
- for (; D; D = D->getNextClassCategory())
- visitDeclRef(D);
- }
- void visitObjCInterfaceDeclAttrs(ObjCInterfaceDecl *D) {
- setPointer("typeptr", D->getTypeForDecl());
- setFlag("forward_decl", !D->isThisDeclarationADefinition());
- setFlag("implicit_interface", D->isImplicitInterfaceDecl());
- }
- void visitObjCInterfaceDeclChildren(ObjCInterfaceDecl *D) {
- visitDeclRef("super", D->getSuperClass());
- visitDeclRef("implementation", D->getImplementation());
- if (D->protocol_begin() != D->protocol_end()) {
- TemporaryContainer C(*this, "protocols");
- for (ObjCInterfaceDecl::protocol_iterator
- I = D->protocol_begin(), E = D->protocol_end(); I != E; ++I)
- visitDeclRef(*I);
- }
- visitCategoryList(D->getCategoryList());
- }
- void visitObjCInterfaceDeclAsContext(ObjCInterfaceDecl *D) {
- visitDeclContext(D);
- }
- // ObjCCategoryDecl
- void visitObjCCategoryDeclAttrs(ObjCCategoryDecl *D) {
- setFlag("extension", D->IsClassExtension());
- setFlag("synth_bitfield", D->hasSynthBitfield());
- }
- void visitObjCCategoryDeclChildren(ObjCCategoryDecl *D) {
- visitDeclRef("interface", D->getClassInterface());
- visitDeclRef("implementation", D->getImplementation());
- if (D->protocol_begin() != D->protocol_end()) {
- TemporaryContainer C(*this, "protocols");
- for (ObjCCategoryDecl::protocol_iterator
- I = D->protocol_begin(), E = D->protocol_end(); I != E; ++I)
- visitDeclRef(*I);
- }
- }
- void visitObjCCategoryDeclAsContext(ObjCCategoryDecl *D) {
- visitDeclContext(D);
- }
- // ObjCCategoryImplDecl
- void visitObjCCategoryImplDeclAttrs(ObjCCategoryImplDecl *D) {
- set("identifier", D->getName());
- }
- void visitObjCCategoryImplDeclChildren(ObjCCategoryImplDecl *D) {
- visitDeclRef(D->getCategoryDecl());
- }
- // ObjCImplementationDecl
- void visitObjCImplementationDeclAttrs(ObjCImplementationDecl *D) {
- setFlag("synth_bitfield", D->hasSynthBitfield());
- set("identifier", D->getName());
- }
- void visitObjCImplementationDeclChildren(ObjCImplementationDecl *D) {
- visitDeclRef("super", D->getSuperClass());
- if (D->init_begin() != D->init_end()) {
- TemporaryContainer C(*this, "initializers");
- for (ObjCImplementationDecl::init_iterator
- I = D->init_begin(), E = D->init_end(); I != E; ++I)
- dispatch(*I);
- }
- }
- // ObjCProtocolDecl
- void visitObjCProtocolDeclChildren(ObjCProtocolDecl *D) {
- if (!D->isThisDeclarationADefinition())
- return;
-
- if (D->protocol_begin() != D->protocol_end()) {
- TemporaryContainer C(*this, "protocols");
- for (ObjCInterfaceDecl::protocol_iterator
- I = D->protocol_begin(), E = D->protocol_end(); I != E; ++I)
- visitDeclRef(*I);
- }
- }
- void visitObjCProtocolDeclAsContext(ObjCProtocolDecl *D) {
- if (!D->isThisDeclarationADefinition())
- return;
-
- visitDeclContext(D);
- }
- // ObjCMethodDecl
- void visitObjCMethodDeclAttrs(ObjCMethodDecl *D) {
- // decl qualifier?
- // implementation control?
- setFlag("instance", D->isInstanceMethod());
- setFlag("variadic", D->isVariadic());
- setFlag("synthesized", D->isSynthesized());
- setFlag("defined", D->isDefined());
- setFlag("related_result_type", D->hasRelatedResultType());
- }
- void visitObjCMethodDeclChildren(ObjCMethodDecl *D) {
- dispatch(D->getResultType());
- for (ObjCMethodDecl::param_iterator
- I = D->param_begin(), E = D->param_end(); I != E; ++I)
- dispatch(*I);
- if (D->isThisDeclarationADefinition())
- dispatch(D->getBody());
- }
- // ObjCIvarDecl
- void setAccessControl(StringRef prop, ObjCIvarDecl::AccessControl AC) {
- switch (AC) {
- case ObjCIvarDecl::None: return set(prop, "none");
- case ObjCIvarDecl::Private: return set(prop, "private");
- case ObjCIvarDecl::Protected: return set(prop, "protected");
- case ObjCIvarDecl::Public: return set(prop, "public");
- case ObjCIvarDecl::Package: return set(prop, "package");
- }
- }
- void visitObjCIvarDeclAttrs(ObjCIvarDecl *D) {
- setFlag("synthesize", D->getSynthesize());
- setAccessControl("access", D->getAccessControl());
- }
- // ObjCCompatibleAliasDecl
- void visitObjCCompatibleAliasDeclChildren(ObjCCompatibleAliasDecl *D) {
- visitDeclRef(D->getClassInterface());
- }
- // FIXME: ObjCPropertyDecl
- // FIXME: ObjCPropertyImplDecl
- //---- Types -----------------------------------------------------//
- void dispatch(TypeLoc TL) {
- dispatch(TL.getType()); // for now
- }
- void dispatch(QualType T) {
- if (T.hasLocalQualifiers()) {
- push("QualType");
- Qualifiers Qs = T.getLocalQualifiers();
- setFlag("const", Qs.hasConst());
- setFlag("volatile", Qs.hasVolatile());
- setFlag("restrict", Qs.hasRestrict());
- if (Qs.hasAddressSpace()) setInteger("addrspace", Qs.getAddressSpace());
- if (Qs.hasObjCGCAttr()) {
- switch (Qs.getObjCGCAttr()) {
- case Qualifiers::Weak: set("gc", "weak"); break;
- case Qualifiers::Strong: set("gc", "strong"); break;
- case Qualifiers::GCNone: llvm_unreachable("explicit none");
- }
- }
-
- completeAttrs();
- dispatch(QualType(T.getTypePtr(), 0));
- pop();
- return;
- }
- Type *Ty = const_cast<Type*>(T.getTypePtr());
- push(getTypeKindName(Ty));
- XMLTypeVisitor<XMLDumper>::dispatch(const_cast<Type*>(T.getTypePtr()));
- pop();
- }
- void setCallingConv(CallingConv CC) {
- switch (CC) {
- case CC_Default: return;
- case CC_C: return set("cc", "cdecl");
- case CC_X86FastCall: return set("cc", "x86_fastcall");
- case CC_X86StdCall: return set("cc", "x86_stdcall");
- case CC_X86ThisCall: return set("cc", "x86_thiscall");
- case CC_X86Pascal: return set("cc", "x86_pascal");
- case CC_AAPCS: return set("cc", "aapcs");
- case CC_AAPCS_VFP: return set("cc", "aapcs_vfp");
- }
- }
- void visitTypeAttrs(Type *D) {
- setPointer(D);
- setFlag("dependent", D->isDependentType());
- setFlag("variably_modified", D->isVariablyModifiedType());
- setPointer("canonical", D->getCanonicalTypeInternal().getAsOpaquePtr());
- }
- void visitPointerTypeChildren(PointerType *T) {
- dispatch(T->getPointeeType());
- }
- void visitReferenceTypeChildren(ReferenceType *T) {
- dispatch(T->getPointeeType());
- }
- void visitObjCObjectPointerTypeChildren(ObjCObjectPointerType *T) {
- dispatch(T->getPointeeType());
- }
- void visitBlockPointerTypeChildren(BlockPointerType *T) {
- dispatch(T->getPointeeType());
- }
- // Types that just wrap declarations.
- void visitTagTypeChildren(TagType *T) {
- visitDeclRef(T->getDecl());
- }
- void visitTypedefTypeChildren(TypedefType *T) {
- visitDeclRef(T->getDecl());
- }
- void visitObjCInterfaceTypeChildren(ObjCInterfaceType *T) {
- visitDeclRef(T->getDecl());
- }
- void visitUnresolvedUsingTypeChildren(UnresolvedUsingType *T) {
- visitDeclRef(T->getDecl());
- }
- void visitInjectedClassNameTypeChildren(InjectedClassNameType *T) {
- visitDeclRef(T->getDecl());
- }
- void visitFunctionTypeAttrs(FunctionType *T) {
- setFlag("noreturn", T->getNoReturnAttr());
- setCallingConv(T->getCallConv());
- if (T->getHasRegParm()) setInteger("regparm", T->getRegParmType());
- }
- void visitFunctionTypeChildren(FunctionType *T) {
- dispatch(T->getResultType());
- }
- void visitFunctionProtoTypeAttrs(FunctionProtoType *T) {
- setFlag("const", T->getTypeQuals() & Qualifiers::Const);
- setFlag("volatile", T->getTypeQuals() & Qualifiers::Volatile);
- setFlag("restrict", T->getTypeQuals() & Qualifiers::Restrict);
- }
- void visitFunctionProtoTypeChildren(FunctionProtoType *T) {
- push("parameters");
- setFlag("variadic", T->isVariadic());
- completeAttrs();
- for (FunctionProtoType::arg_type_iterator
- I = T->arg_type_begin(), E = T->arg_type_end(); I != E; ++I)
- dispatch(*I);
- pop();
- if (T->hasDynamicExceptionSpec()) {
- push("exception_specifiers");
- setFlag("any", T->getExceptionSpecType() == EST_MSAny);
- completeAttrs();
- for (FunctionProtoType::exception_iterator
- I = T->exception_begin(), E = T->exception_end(); I != E; ++I)
- dispatch(*I);
- pop();
- }
- // FIXME: noexcept specifier
- }
- void visitTemplateSpecializationTypeChildren(TemplateSpecializationType *T) {
- if (const RecordType *RT = T->getAs<RecordType>())
- visitDeclRef(RT->getDecl());
- // TODO: TemplateName
- push("template_arguments");
- completeAttrs();
- for (unsigned I = 0, E = T->getNumArgs(); I != E; ++I)
- dispatch(T->getArg(I));
- pop();
- }
- //---- Statements ------------------------------------------------//
- void dispatch(Stmt *S) {
- // FIXME: this is not really XML at all
- push("Stmt");
- out << ">\n";
- Stack.back().State = NS_Children; // explicitly become non-lazy
- S->dump(out, Context.getSourceManager());
- out << '\n';
- pop();
- }
- };
- }
- void Decl::dumpXML() const {
- dumpXML(llvm::errs());
- }
- void Decl::dumpXML(raw_ostream &out) const {
- XMLDumper(out, getASTContext()).dispatch(const_cast<Decl*>(this));
- }
- #else /* ifndef NDEBUG */
- void Decl::dumpXML() const {}
- void Decl::dumpXML(raw_ostream &out) const {}
- #endif
|