Home | History | Annotate | Download | only in AST
      1 //===--- DumpXML.cpp - Detailed XML dumping ---------------------*- C++ -*-===//
      2 //
      3 //                     The LLVM Compiler Infrastructure
      4 //
      5 // This file is distributed under the University of Illinois Open Source
      6 // License. See LICENSE.TXT for details.
      7 //
      8 //===----------------------------------------------------------------------===//
      9 //
     10 //  This file defines the Decl::dumpXML() method, a debugging tool to
     11 //  print a detailed graph of an AST in an unspecified XML format.
     12 //
     13 //  There is no guarantee of stability for this format.
     14 //
     15 //===----------------------------------------------------------------------===//
     16 
     17 // Only pay for this in code size in assertions-enabled builds.
     18 
     19 #include "clang/AST/ASTContext.h"
     20 #include "clang/AST/Decl.h"
     21 #include "clang/AST/DeclCXX.h"
     22 #include "clang/AST/DeclFriend.h"
     23 #include "clang/AST/DeclObjC.h"
     24 #include "clang/AST/DeclTemplate.h"
     25 #include "clang/AST/DeclVisitor.h"
     26 #include "clang/AST/Expr.h"
     27 #include "clang/AST/ExprCXX.h"
     28 #include "clang/AST/ExprObjC.h"
     29 #include "clang/AST/NestedNameSpecifier.h"
     30 #include "clang/AST/Stmt.h"
     31 #include "clang/AST/StmtCXX.h"
     32 #include "clang/AST/StmtObjC.h"
     33 #include "clang/AST/StmtVisitor.h"
     34 #include "clang/AST/TemplateBase.h"
     35 #include "clang/AST/TemplateName.h"
     36 #include "clang/AST/Type.h"
     37 #include "clang/AST/TypeLoc.h"
     38 #include "clang/AST/TypeLocVisitor.h"
     39 #include "clang/AST/TypeVisitor.h"
     40 #include "clang/AST/Expr.h"
     41 #include "clang/AST/ExprCXX.h"
     42 #include "llvm/ADT/SmallString.h"
     43 
     44 using namespace clang;
     45 
     46 #ifndef NDEBUG
     47 
     48 namespace {
     49 
     50 enum NodeState {
     51   NS_Attrs, NS_LazyChildren, NS_Children
     52 };
     53 
     54 struct Node {
     55   StringRef Name;
     56   NodeState State;
     57   Node(StringRef name) : Name(name), State(NS_Attrs) {}
     58 
     59   bool isDoneWithAttrs() const { return State != NS_Attrs; }
     60 };
     61 
     62 template <class Impl> struct XMLDeclVisitor {
     63 #define DISPATCH(NAME, CLASS) \
     64   static_cast<Impl*>(this)->NAME(static_cast<CLASS*>(D))
     65 
     66   void dispatch(Decl *D) {
     67     switch (D->getKind()) {
     68 #define DECL(DERIVED, BASE) \
     69       case Decl::DERIVED: \
     70         DISPATCH(dispatch##DERIVED##DeclAttrs, DERIVED##Decl); \
     71         static_cast<Impl*>(this)->completeAttrs(); \
     72         DISPATCH(dispatch##DERIVED##DeclChildren, DERIVED##Decl); \
     73         DISPATCH(dispatch##DERIVED##DeclAsContext, DERIVED##Decl); \
     74         break;
     75 #define ABSTRACT_DECL(DECL)
     76 #include "clang/AST/DeclNodes.inc"
     77     }
     78   }
     79 
     80 #define DECL(DERIVED, BASE) \
     81   void dispatch##DERIVED##DeclAttrs(DERIVED##Decl *D) { \
     82     DISPATCH(dispatch##BASE##Attrs, BASE); \
     83     DISPATCH(visit##DERIVED##DeclAttrs, DERIVED##Decl); \
     84   } \
     85   void visit##DERIVED##DeclAttrs(DERIVED##Decl *D) {} \
     86   void dispatch##DERIVED##DeclChildren(DERIVED##Decl *D) { \
     87     DISPATCH(dispatch##BASE##Children, BASE); \
     88     DISPATCH(visit##DERIVED##DeclChildren, DERIVED##Decl); \
     89   } \
     90   void visit##DERIVED##DeclChildren(DERIVED##Decl *D) {} \
     91   void dispatch##DERIVED##DeclAsContext(DERIVED##Decl *D) { \
     92     DISPATCH(dispatch##BASE##AsContext, BASE); \
     93     DISPATCH(visit##DERIVED##DeclAsContext, DERIVED##Decl); \
     94   } \
     95   void visit##DERIVED##DeclAsContext(DERIVED##Decl *D) {}
     96 #include "clang/AST/DeclNodes.inc"
     97 
     98   void dispatchDeclAttrs(Decl *D) {
     99     DISPATCH(visitDeclAttrs, Decl);
    100   }
    101   void visitDeclAttrs(Decl *D) {}
    102 
    103   void dispatchDeclChildren(Decl *D) {
    104     DISPATCH(visitDeclChildren, Decl);
    105   }
    106   void visitDeclChildren(Decl *D) {}
    107 
    108   void dispatchDeclAsContext(Decl *D) {
    109     DISPATCH(visitDeclAsContext, Decl);
    110   }
    111   void visitDeclAsContext(Decl *D) {}
    112 
    113 #undef DISPATCH
    114 };
    115 
    116 template <class Impl> struct XMLTypeVisitor {
    117 #define DISPATCH(NAME, CLASS) \
    118   static_cast<Impl*>(this)->NAME(static_cast<CLASS*>(T))
    119 
    120   void dispatch(Type *T) {
    121     switch (T->getTypeClass()) {
    122 #define TYPE(DERIVED, BASE) \
    123       case Type::DERIVED: \
    124         DISPATCH(dispatch##DERIVED##TypeAttrs, DERIVED##Type); \
    125         static_cast<Impl*>(this)->completeAttrs(); \
    126         DISPATCH(dispatch##DERIVED##TypeChildren, DERIVED##Type); \
    127         break;
    128 #define ABSTRACT_TYPE(DERIVED, BASE)
    129 #include "clang/AST/TypeNodes.def"
    130     }
    131   }
    132 
    133 #define TYPE(DERIVED, BASE) \
    134   void dispatch##DERIVED##TypeAttrs(DERIVED##Type *T) { \
    135     DISPATCH(dispatch##BASE##Attrs, BASE); \
    136     DISPATCH(visit##DERIVED##TypeAttrs, DERIVED##Type); \
    137   } \
    138   void visit##DERIVED##TypeAttrs(DERIVED##Type *T) {} \
    139   void dispatch##DERIVED##TypeChildren(DERIVED##Type *T) { \
    140     DISPATCH(dispatch##BASE##Children, BASE); \
    141     DISPATCH(visit##DERIVED##TypeChildren, DERIVED##Type); \
    142   } \
    143   void visit##DERIVED##TypeChildren(DERIVED##Type *T) {}
    144 #include "clang/AST/TypeNodes.def"
    145 
    146   void dispatchTypeAttrs(Type *T) {
    147     DISPATCH(visitTypeAttrs, Type);
    148   }
    149   void visitTypeAttrs(Type *T) {}
    150 
    151   void dispatchTypeChildren(Type *T) {
    152     DISPATCH(visitTypeChildren, Type);
    153   }
    154   void visitTypeChildren(Type *T) {}
    155 
    156 #undef DISPATCH
    157 };
    158 
    159 static StringRef getTypeKindName(Type *T) {
    160   switch (T->getTypeClass()) {
    161 #define TYPE(DERIVED, BASE) case Type::DERIVED: return #DERIVED "Type";
    162 #define ABSTRACT_TYPE(DERIVED, BASE)
    163 #include "clang/AST/TypeNodes.def"
    164   }
    165 
    166   llvm_unreachable("unknown type kind!");
    167 }
    168 
    169 struct XMLDumper : public XMLDeclVisitor<XMLDumper>,
    170                    public XMLTypeVisitor<XMLDumper> {
    171   raw_ostream &out;
    172   ASTContext &Context;
    173   SmallVector<Node, 16> Stack;
    174   unsigned Indent;
    175   explicit XMLDumper(raw_ostream &OS, ASTContext &context)
    176     : out(OS), Context(context), Indent(0) {}
    177 
    178   void indent() {
    179     for (unsigned I = Indent; I; --I)
    180       out << ' ';
    181   }
    182 
    183   /// Push a new node on the stack.
    184   void push(StringRef name) {
    185     if (!Stack.empty()) {
    186       assert(Stack.back().isDoneWithAttrs());
    187       if (Stack.back().State == NS_LazyChildren) {
    188         Stack.back().State = NS_Children;
    189         out << ">\n";
    190       }
    191       Indent++;
    192       indent();
    193     }
    194     Stack.push_back(Node(name));
    195     out << '<' << name;
    196   }
    197 
    198   /// Set the given attribute to the given value.
    199   void set(StringRef attr, StringRef value) {
    200     assert(!Stack.empty() && !Stack.back().isDoneWithAttrs());
    201     out << ' ' << attr << '=' << '"' << value << '"'; // TODO: quotation
    202   }
    203 
    204   /// Finish attributes.
    205   void completeAttrs() {
    206     assert(!Stack.empty() && !Stack.back().isDoneWithAttrs());
    207     Stack.back().State = NS_LazyChildren;
    208   }
    209 
    210   /// Pop a node.
    211   void pop() {
    212     assert(!Stack.empty() && Stack.back().isDoneWithAttrs());
    213     if (Stack.back().State == NS_LazyChildren) {
    214       out << "/>\n";
    215     } else {
    216       indent();
    217       out << "</" << Stack.back().Name << ">\n";
    218     }
    219     if (Stack.size() > 1) Indent--;
    220     Stack.pop_back();
    221   }
    222 
    223   //---- General utilities -------------------------------------------//
    224 
    225   void setPointer(StringRef prop, const void *p) {
    226     SmallString<10> buffer;
    227     llvm::raw_svector_ostream os(buffer);
    228     os << p;
    229     os.flush();
    230     set(prop, buffer);
    231   }
    232 
    233   void setPointer(void *p) {
    234     setPointer("ptr", p);
    235   }
    236 
    237   void setInteger(StringRef prop, const llvm::APSInt &v) {
    238     set(prop, v.toString(10));
    239   }
    240 
    241   void setInteger(StringRef prop, unsigned n) {
    242     SmallString<10> buffer;
    243     llvm::raw_svector_ostream os(buffer);
    244     os << n;
    245     os.flush();
    246     set(prop, buffer);
    247   }
    248 
    249   void setFlag(StringRef prop, bool flag) {
    250     if (flag) set(prop, "true");
    251   }
    252 
    253   void setName(DeclarationName Name) {
    254     if (!Name)
    255       return set("name", "");
    256 
    257     // Common case.
    258     if (Name.isIdentifier())
    259       return set("name", Name.getAsIdentifierInfo()->getName());
    260 
    261     set("name", Name.getAsString());
    262   }
    263 
    264   class TemporaryContainer {
    265     XMLDumper &Dumper;
    266   public:
    267     TemporaryContainer(XMLDumper &dumper, StringRef name)
    268       : Dumper(dumper) {
    269       Dumper.push(name);
    270       Dumper.completeAttrs();
    271     }
    272 
    273     ~TemporaryContainer() {
    274       Dumper.pop();
    275     }
    276   };
    277 
    278   void visitTemplateParameters(TemplateParameterList *L) {
    279     push("template_parameters");
    280     completeAttrs();
    281     for (TemplateParameterList::iterator
    282            I = L->begin(), E = L->end(); I != E; ++I)
    283       dispatch(*I);
    284     pop();
    285   }
    286 
    287   void visitTemplateArguments(const TemplateArgumentList &L) {
    288     push("template_arguments");
    289     completeAttrs();
    290     for (unsigned I = 0, E = L.size(); I != E; ++I)
    291       dispatch(L[I]);
    292     pop();
    293   }
    294 
    295   /// Visits a reference to the given declaration.
    296   void visitDeclRef(Decl *D) {
    297     push(D->getDeclKindName());
    298     setPointer("ref", D);
    299     completeAttrs();
    300     pop();
    301   }
    302   void visitDeclRef(StringRef Name, Decl *D) {
    303     TemporaryContainer C(*this, Name);
    304     if (D) visitDeclRef(D);
    305   }
    306 
    307   void dispatch(const TemplateArgument &A) {
    308     switch (A.getKind()) {
    309     case TemplateArgument::Null: {
    310       TemporaryContainer C(*this, "null");
    311       break;
    312     }
    313     case TemplateArgument::Type: {
    314       dispatch(A.getAsType());
    315       break;
    316     }
    317     case TemplateArgument::Template:
    318     case TemplateArgument::TemplateExpansion:
    319       // FIXME: Implement!
    320       break;
    321 
    322     case TemplateArgument::Declaration: {
    323       if (Decl *D = A.getAsDecl())
    324         visitDeclRef(D);
    325       break;
    326     }
    327     case TemplateArgument::Integral: {
    328       push("integer");
    329       setInteger("value", *A.getAsIntegral());
    330       completeAttrs();
    331       pop();
    332       break;
    333     }
    334     case TemplateArgument::Expression: {
    335       dispatch(A.getAsExpr());
    336       break;
    337     }
    338     case TemplateArgument::Pack: {
    339       for (TemplateArgument::pack_iterator P = A.pack_begin(),
    340                                         PEnd = A.pack_end();
    341            P != PEnd; ++P)
    342         dispatch(*P);
    343       break;
    344     }
    345     }
    346   }
    347 
    348   void dispatch(const TemplateArgumentLoc &A) {
    349     dispatch(A.getArgument());
    350   }
    351 
    352   //---- Declarations ------------------------------------------------//
    353   // Calls are made in this order:
    354   //   # Enter a new node.
    355   //   push("FieldDecl")
    356   //
    357   //   # In this phase, attributes are set on the node.
    358   //   visitDeclAttrs(D)
    359   //   visitNamedDeclAttrs(D)
    360   //   ...
    361   //   visitFieldDeclAttrs(D)
    362   //
    363   //   # No more attributes after this point.
    364   //   completeAttrs()
    365   //
    366   //   # Create "header" child nodes, i.e. those which logically
    367   //   # belong to the declaration itself.
    368   //   visitDeclChildren(D)
    369   //   visitNamedDeclChildren(D)
    370   //   ...
    371   //   visitFieldDeclChildren(D)
    372   //
    373   //   # Create nodes for the lexical children.
    374   //   visitDeclAsContext(D)
    375   //   visitNamedDeclAsContext(D)
    376   //   ...
    377   //   visitFieldDeclAsContext(D)
    378   //
    379   //   # Finish the node.
    380   //   pop();
    381   void dispatch(Decl *D) {
    382     push(D->getDeclKindName());
    383     XMLDeclVisitor<XMLDumper>::dispatch(D);
    384     pop();
    385   }
    386   void visitDeclAttrs(Decl *D) {
    387     setPointer(D);
    388   }
    389 
    390   /// Visit all the lexical decls in the given context.
    391   void visitDeclContext(DeclContext *DC) {
    392     for (DeclContext::decl_iterator
    393            I = DC->decls_begin(), E = DC->decls_end(); I != E; ++I)
    394       dispatch(*I);
    395 
    396     // FIXME: point out visible declarations not in lexical context?
    397   }
    398 
    399   /// Set the "access" attribute on the current node according to the
    400   /// given specifier.
    401   void setAccess(AccessSpecifier AS) {
    402     switch (AS) {
    403     case AS_public: return set("access", "public");
    404     case AS_protected: return set("access", "protected");
    405     case AS_private: return set("access", "private");
    406     case AS_none: llvm_unreachable("explicit forbidden access");
    407     }
    408   }
    409 
    410   template <class T> void visitRedeclarableAttrs(T *D) {
    411     if (T *Prev = D->getPreviousDecl())
    412       setPointer("previous", Prev);
    413   }
    414 
    415 
    416   // TranslationUnitDecl
    417   void visitTranslationUnitDeclAsContext(TranslationUnitDecl *D) {
    418     visitDeclContext(D);
    419   }
    420 
    421   // LinkageSpecDecl
    422   void visitLinkageSpecDeclAttrs(LinkageSpecDecl *D) {
    423     StringRef lang = "";
    424     switch (D->getLanguage()) {
    425     case LinkageSpecDecl::lang_c: lang = "C"; break;
    426     case LinkageSpecDecl::lang_cxx: lang = "C++"; break;
    427     }
    428     set("lang", lang);
    429   }
    430   void visitLinkageSpecDeclAsContext(LinkageSpecDecl *D) {
    431     visitDeclContext(D);
    432   }
    433 
    434   // NamespaceDecl
    435   void visitNamespaceDeclAttrs(NamespaceDecl *D) {
    436     setFlag("inline", D->isInline());
    437     if (!D->isOriginalNamespace())
    438       setPointer("original", D->getOriginalNamespace());
    439   }
    440   void visitNamespaceDeclAsContext(NamespaceDecl *D) {
    441     visitDeclContext(D);
    442   }
    443 
    444   // NamedDecl
    445   void visitNamedDeclAttrs(NamedDecl *D) {
    446     setName(D->getDeclName());
    447   }
    448 
    449   // ValueDecl
    450   void visitValueDeclChildren(ValueDecl *D) {
    451     dispatch(D->getType());
    452   }
    453 
    454   // DeclaratorDecl
    455   void visitDeclaratorDeclChildren(DeclaratorDecl *D) {
    456     //dispatch(D->getTypeSourceInfo()->getTypeLoc());
    457   }
    458 
    459   // VarDecl
    460   void visitVarDeclAttrs(VarDecl *D) {
    461     visitRedeclarableAttrs(D);
    462     if (D->getStorageClass() != SC_None)
    463       set("storage",
    464           VarDecl::getStorageClassSpecifierString(D->getStorageClass()));
    465     StringRef initStyle = "";
    466     switch (D->getInitStyle()) {
    467     case VarDecl::CInit: initStyle = "c"; break;
    468     case VarDecl::CallInit: initStyle = "call"; break;
    469     case VarDecl::ListInit: initStyle = "list"; break;
    470     }
    471     set("initstyle", initStyle);
    472     setFlag("nrvo", D->isNRVOVariable());
    473     // TODO: instantiation, etc.
    474   }
    475   void visitVarDeclChildren(VarDecl *D) {
    476     if (D->hasInit()) dispatch(D->getInit());
    477   }
    478 
    479   // ParmVarDecl?
    480 
    481   // FunctionDecl
    482   void visitFunctionDeclAttrs(FunctionDecl *D) {
    483     visitRedeclarableAttrs(D);
    484     setFlag("pure", D->isPure());
    485     setFlag("trivial", D->isTrivial());
    486     setFlag("returnzero", D->hasImplicitReturnZero());
    487     setFlag("prototype", D->hasWrittenPrototype());
    488     setFlag("deleted", D->isDeletedAsWritten());
    489     if (D->getStorageClass() != SC_None)
    490       set("storage",
    491           VarDecl::getStorageClassSpecifierString(D->getStorageClass()));
    492     setFlag("inline", D->isInlineSpecified());
    493     if (const AsmLabelAttr *ALA = D->getAttr<AsmLabelAttr>())
    494       set("asmlabel", ALA->getLabel());
    495     // TODO: instantiation, etc.
    496   }
    497   void visitFunctionDeclChildren(FunctionDecl *D) {
    498     for (FunctionDecl::param_iterator
    499            I = D->param_begin(), E = D->param_end(); I != E; ++I)
    500       dispatch(*I);
    501     for (llvm::ArrayRef<NamedDecl*>::iterator
    502            I = D->getDeclsInPrototypeScope().begin(), E = D->getDeclsInPrototypeScope().end();
    503          I != E; ++I)
    504       dispatch(*I);
    505     if (D->doesThisDeclarationHaveABody())
    506       dispatch(D->getBody());
    507   }
    508 
    509   // CXXMethodDecl ?
    510   // CXXConstructorDecl ?
    511   // CXXDestructorDecl ?
    512   // CXXConversionDecl ?
    513 
    514   void dispatch(CXXCtorInitializer *Init) {
    515     // TODO
    516   }
    517 
    518   // FieldDecl
    519   void visitFieldDeclAttrs(FieldDecl *D) {
    520     setFlag("mutable", D->isMutable());
    521   }
    522   void visitFieldDeclChildren(FieldDecl *D) {
    523     if (D->isBitField()) {
    524       TemporaryContainer C(*this, "bitwidth");
    525       dispatch(D->getBitWidth());
    526     }
    527     // TODO: C++0x member initializer
    528   }
    529 
    530   // EnumConstantDecl
    531   void visitEnumConstantDeclChildren(EnumConstantDecl *D) {
    532     // value in any case?
    533     if (D->getInitExpr()) dispatch(D->getInitExpr());
    534   }
    535 
    536   // IndirectFieldDecl
    537   void visitIndirectFieldDeclChildren(IndirectFieldDecl *D) {
    538     for (IndirectFieldDecl::chain_iterator
    539            I = D->chain_begin(), E = D->chain_end(); I != E; ++I) {
    540       NamedDecl *VD = const_cast<NamedDecl*>(*I);
    541       push(isa<VarDecl>(VD) ? "variable" : "field");
    542       setPointer("ptr", VD);
    543       completeAttrs();
    544       pop();
    545     }
    546   }
    547 
    548   // TypeDecl
    549   void visitTypeDeclAttrs(TypeDecl *D) {
    550     setPointer("typeptr", D->getTypeForDecl());
    551   }
    552 
    553   // TypedefDecl
    554   void visitTypedefDeclAttrs(TypedefDecl *D) {
    555     visitRedeclarableAttrs<TypedefNameDecl>(D);
    556   }
    557   void visitTypedefDeclChildren(TypedefDecl *D) {
    558     dispatch(D->getTypeSourceInfo()->getTypeLoc());
    559   }
    560 
    561   // TypeAliasDecl
    562   void visitTypeAliasDeclAttrs(TypeAliasDecl *D) {
    563     visitRedeclarableAttrs<TypedefNameDecl>(D);
    564   }
    565   void visitTypeAliasDeclChildren(TypeAliasDecl *D) {
    566     dispatch(D->getTypeSourceInfo()->getTypeLoc());
    567   }
    568 
    569   // TagDecl
    570   void visitTagDeclAttrs(TagDecl *D) {
    571     visitRedeclarableAttrs(D);
    572   }
    573   void visitTagDeclAsContext(TagDecl *D) {
    574     visitDeclContext(D);
    575   }
    576 
    577   // EnumDecl
    578   void visitEnumDeclAttrs(EnumDecl *D) {
    579     setFlag("scoped", D->isScoped());
    580     setFlag("fixed", D->isFixed());
    581   }
    582   void visitEnumDeclChildren(EnumDecl *D) {
    583     {
    584       TemporaryContainer C(*this, "promotion_type");
    585       dispatch(D->getPromotionType());
    586     }
    587     {
    588       TemporaryContainer C(*this, "integer_type");
    589       dispatch(D->getIntegerType());
    590     }
    591   }
    592 
    593   // RecordDecl ?
    594 
    595   void visitCXXRecordDeclChildren(CXXRecordDecl *D) {
    596     if (!D->isThisDeclarationADefinition()) return;
    597 
    598     for (CXXRecordDecl::base_class_iterator
    599            I = D->bases_begin(), E = D->bases_end(); I != E; ++I) {
    600       push("base");
    601       setAccess(I->getAccessSpecifier());
    602       completeAttrs();
    603       dispatch(I->getTypeSourceInfo()->getTypeLoc());
    604       pop();
    605     }
    606   }
    607 
    608   // ClassTemplateSpecializationDecl ?
    609 
    610   // FileScopeAsmDecl ?
    611 
    612   // BlockDecl
    613   void visitBlockDeclAttrs(BlockDecl *D) {
    614     setFlag("variadic", D->isVariadic());
    615   }
    616   void visitBlockDeclChildren(BlockDecl *D) {
    617     for (FunctionDecl::param_iterator
    618            I = D->param_begin(), E = D->param_end(); I != E; ++I)
    619       dispatch(*I);
    620     dispatch(D->getBody());
    621   }
    622 
    623   // AccessSpecDecl
    624   void visitAccessSpecDeclAttrs(AccessSpecDecl *D) {
    625     setAccess(D->getAccess());
    626   }
    627 
    628   // TemplateDecl
    629   void visitTemplateDeclChildren(TemplateDecl *D) {
    630     visitTemplateParameters(D->getTemplateParameters());
    631     if (D->getTemplatedDecl())
    632       dispatch(D->getTemplatedDecl());
    633   }
    634 
    635   // FunctionTemplateDecl
    636   void visitFunctionTemplateDeclAttrs(FunctionTemplateDecl *D) {
    637     visitRedeclarableAttrs(D);
    638   }
    639   void visitFunctionTemplateDeclChildren(FunctionTemplateDecl *D) {
    640     // Mention all the specializations which don't have explicit
    641     // declarations elsewhere.
    642     for (FunctionTemplateDecl::spec_iterator
    643            I = D->spec_begin(), E = D->spec_end(); I != E; ++I) {
    644       FunctionTemplateSpecializationInfo *Info
    645         = I->getTemplateSpecializationInfo();
    646 
    647       bool Unknown = false;
    648       switch (Info->getTemplateSpecializationKind()) {
    649       case TSK_ImplicitInstantiation: Unknown = false; break;
    650       case TSK_Undeclared: Unknown = true; break;
    651 
    652       // These will be covered at their respective sites.
    653       case TSK_ExplicitSpecialization: continue;
    654       case TSK_ExplicitInstantiationDeclaration: continue;
    655       case TSK_ExplicitInstantiationDefinition: continue;
    656       }
    657 
    658       TemporaryContainer C(*this,
    659                            Unknown ? "uninstantiated" : "instantiation");
    660       visitTemplateArguments(*Info->TemplateArguments);
    661       dispatch(Info->Function);
    662     }
    663   }
    664 
    665   // ClasTemplateDecl
    666   void visitClassTemplateDeclAttrs(ClassTemplateDecl *D) {
    667     visitRedeclarableAttrs(D);
    668   }
    669   void visitClassTemplateDeclChildren(ClassTemplateDecl *D) {
    670     // Mention all the specializations which don't have explicit
    671     // declarations elsewhere.
    672     for (ClassTemplateDecl::spec_iterator
    673            I = D->spec_begin(), E = D->spec_end(); I != E; ++I) {
    674 
    675       bool Unknown = false;
    676       switch (I->getTemplateSpecializationKind()) {
    677       case TSK_ImplicitInstantiation: Unknown = false; break;
    678       case TSK_Undeclared: Unknown = true; break;
    679 
    680       // These will be covered at their respective sites.
    681       case TSK_ExplicitSpecialization: continue;
    682       case TSK_ExplicitInstantiationDeclaration: continue;
    683       case TSK_ExplicitInstantiationDefinition: continue;
    684       }
    685 
    686       TemporaryContainer C(*this,
    687                            Unknown ? "uninstantiated" : "instantiation");
    688       visitTemplateArguments(I->getTemplateArgs());
    689       dispatch(*I);
    690     }
    691   }
    692 
    693   // TemplateTypeParmDecl
    694   void visitTemplateTypeParmDeclAttrs(TemplateTypeParmDecl *D) {
    695     setInteger("depth", D->getDepth());
    696     setInteger("index", D->getIndex());
    697   }
    698   void visitTemplateTypeParmDeclChildren(TemplateTypeParmDecl *D) {
    699     if (D->hasDefaultArgument() && !D->defaultArgumentWasInherited())
    700       dispatch(D->getDefaultArgumentInfo()->getTypeLoc());
    701     // parameter pack?
    702   }
    703 
    704   // NonTypeTemplateParmDecl
    705   void visitNonTypeTemplateParmDeclAttrs(NonTypeTemplateParmDecl *D) {
    706     setInteger("depth", D->getDepth());
    707     setInteger("index", D->getIndex());
    708   }
    709   void visitNonTypeTemplateParmDeclChildren(NonTypeTemplateParmDecl *D) {
    710     if (D->hasDefaultArgument() && !D->defaultArgumentWasInherited())
    711       dispatch(D->getDefaultArgument());
    712     // parameter pack?
    713   }
    714 
    715   // TemplateTemplateParmDecl
    716   void visitTemplateTemplateParmDeclAttrs(TemplateTemplateParmDecl *D) {
    717     setInteger("depth", D->getDepth());
    718     setInteger("index", D->getIndex());
    719   }
    720   void visitTemplateTemplateParmDeclChildren(TemplateTemplateParmDecl *D) {
    721     if (D->hasDefaultArgument() && !D->defaultArgumentWasInherited())
    722       dispatch(D->getDefaultArgument());
    723     // parameter pack?
    724   }
    725 
    726   // FriendDecl
    727   void visitFriendDeclChildren(FriendDecl *D) {
    728     if (TypeSourceInfo *T = D->getFriendType())
    729       dispatch(T->getTypeLoc());
    730     else
    731       dispatch(D->getFriendDecl());
    732   }
    733 
    734   // UsingDirectiveDecl ?
    735   // UsingDecl ?
    736   // UsingShadowDecl ?
    737   // NamespaceAliasDecl ?
    738   // UnresolvedUsingValueDecl ?
    739   // UnresolvedUsingTypenameDecl ?
    740   // StaticAssertDecl ?
    741 
    742   // ObjCImplDecl
    743   void visitObjCImplDeclChildren(ObjCImplDecl *D) {
    744     visitDeclRef(D->getClassInterface());
    745   }
    746   void visitObjCImplDeclAsContext(ObjCImplDecl *D) {
    747     visitDeclContext(D);
    748   }
    749 
    750   // ObjCInterfaceDecl
    751   void visitCategoryList(ObjCCategoryDecl *D) {
    752     if (!D) return;
    753 
    754     TemporaryContainer C(*this, "categories");
    755     for (; D; D = D->getNextClassCategory())
    756       visitDeclRef(D);
    757   }
    758   void visitObjCInterfaceDeclAttrs(ObjCInterfaceDecl *D) {
    759     setPointer("typeptr", D->getTypeForDecl());
    760     setFlag("forward_decl", !D->isThisDeclarationADefinition());
    761     setFlag("implicit_interface", D->isImplicitInterfaceDecl());
    762   }
    763   void visitObjCInterfaceDeclChildren(ObjCInterfaceDecl *D) {
    764     visitDeclRef("super", D->getSuperClass());
    765     visitDeclRef("implementation", D->getImplementation());
    766     if (D->protocol_begin() != D->protocol_end()) {
    767       TemporaryContainer C(*this, "protocols");
    768       for (ObjCInterfaceDecl::protocol_iterator
    769              I = D->protocol_begin(), E = D->protocol_end(); I != E; ++I)
    770         visitDeclRef(*I);
    771     }
    772     visitCategoryList(D->getCategoryList());
    773   }
    774   void visitObjCInterfaceDeclAsContext(ObjCInterfaceDecl *D) {
    775     visitDeclContext(D);
    776   }
    777 
    778   // ObjCCategoryDecl
    779   void visitObjCCategoryDeclAttrs(ObjCCategoryDecl *D) {
    780     setFlag("extension", D->IsClassExtension());
    781     setFlag("synth_bitfield", D->hasSynthBitfield());
    782   }
    783   void visitObjCCategoryDeclChildren(ObjCCategoryDecl *D) {
    784     visitDeclRef("interface", D->getClassInterface());
    785     visitDeclRef("implementation", D->getImplementation());
    786     if (D->protocol_begin() != D->protocol_end()) {
    787       TemporaryContainer C(*this, "protocols");
    788       for (ObjCCategoryDecl::protocol_iterator
    789              I = D->protocol_begin(), E = D->protocol_end(); I != E; ++I)
    790         visitDeclRef(*I);
    791     }
    792   }
    793   void visitObjCCategoryDeclAsContext(ObjCCategoryDecl *D) {
    794     visitDeclContext(D);
    795   }
    796 
    797   // ObjCCategoryImplDecl
    798   void visitObjCCategoryImplDeclAttrs(ObjCCategoryImplDecl *D) {
    799     set("identifier", D->getName());
    800   }
    801   void visitObjCCategoryImplDeclChildren(ObjCCategoryImplDecl *D) {
    802     visitDeclRef(D->getCategoryDecl());
    803   }
    804 
    805   // ObjCImplementationDecl
    806   void visitObjCImplementationDeclAttrs(ObjCImplementationDecl *D) {
    807     setFlag("synth_bitfield", D->hasSynthBitfield());
    808     set("identifier", D->getName());
    809   }
    810   void visitObjCImplementationDeclChildren(ObjCImplementationDecl *D) {
    811     visitDeclRef("super", D->getSuperClass());
    812     if (D->init_begin() != D->init_end()) {
    813       TemporaryContainer C(*this, "initializers");
    814       for (ObjCImplementationDecl::init_iterator
    815              I = D->init_begin(), E = D->init_end(); I != E; ++I)
    816         dispatch(*I);
    817     }
    818   }
    819 
    820   // ObjCProtocolDecl
    821   void visitObjCProtocolDeclChildren(ObjCProtocolDecl *D) {
    822     if (!D->isThisDeclarationADefinition())
    823       return;
    824 
    825     if (D->protocol_begin() != D->protocol_end()) {
    826       TemporaryContainer C(*this, "protocols");
    827       for (ObjCInterfaceDecl::protocol_iterator
    828              I = D->protocol_begin(), E = D->protocol_end(); I != E; ++I)
    829         visitDeclRef(*I);
    830     }
    831   }
    832   void visitObjCProtocolDeclAsContext(ObjCProtocolDecl *D) {
    833     if (!D->isThisDeclarationADefinition())
    834       return;
    835 
    836     visitDeclContext(D);
    837   }
    838 
    839   // ObjCMethodDecl
    840   void visitObjCMethodDeclAttrs(ObjCMethodDecl *D) {
    841     // decl qualifier?
    842     // implementation control?
    843 
    844     setFlag("instance", D->isInstanceMethod());
    845     setFlag("variadic", D->isVariadic());
    846     setFlag("synthesized", D->isSynthesized());
    847     setFlag("defined", D->isDefined());
    848     setFlag("related_result_type", D->hasRelatedResultType());
    849   }
    850   void visitObjCMethodDeclChildren(ObjCMethodDecl *D) {
    851     dispatch(D->getResultType());
    852     for (ObjCMethodDecl::param_iterator
    853            I = D->param_begin(), E = D->param_end(); I != E; ++I)
    854       dispatch(*I);
    855     if (D->isThisDeclarationADefinition())
    856       dispatch(D->getBody());
    857   }
    858 
    859   // ObjCIvarDecl
    860   void setAccessControl(StringRef prop, ObjCIvarDecl::AccessControl AC) {
    861     switch (AC) {
    862     case ObjCIvarDecl::None: return set(prop, "none");
    863     case ObjCIvarDecl::Private: return set(prop, "private");
    864     case ObjCIvarDecl::Protected: return set(prop, "protected");
    865     case ObjCIvarDecl::Public: return set(prop, "public");
    866     case ObjCIvarDecl::Package: return set(prop, "package");
    867     }
    868   }
    869   void visitObjCIvarDeclAttrs(ObjCIvarDecl *D) {
    870     setFlag("synthesize", D->getSynthesize());
    871     setAccessControl("access", D->getAccessControl());
    872   }
    873 
    874   // ObjCCompatibleAliasDecl
    875   void visitObjCCompatibleAliasDeclChildren(ObjCCompatibleAliasDecl *D) {
    876     visitDeclRef(D->getClassInterface());
    877   }
    878 
    879   // FIXME: ObjCPropertyDecl
    880   // FIXME: ObjCPropertyImplDecl
    881 
    882   //---- Types -----------------------------------------------------//
    883   void dispatch(TypeLoc TL) {
    884     dispatch(TL.getType()); // for now
    885   }
    886 
    887   void dispatch(QualType T) {
    888     if (T.hasLocalQualifiers()) {
    889       push("QualType");
    890       Qualifiers Qs = T.getLocalQualifiers();
    891       setFlag("const", Qs.hasConst());
    892       setFlag("volatile", Qs.hasVolatile());
    893       setFlag("restrict", Qs.hasRestrict());
    894       if (Qs.hasAddressSpace()) setInteger("addrspace", Qs.getAddressSpace());
    895       if (Qs.hasObjCGCAttr()) {
    896         switch (Qs.getObjCGCAttr()) {
    897         case Qualifiers::Weak: set("gc", "weak"); break;
    898         case Qualifiers::Strong: set("gc", "strong"); break;
    899         case Qualifiers::GCNone: llvm_unreachable("explicit none");
    900         }
    901       }
    902 
    903       completeAttrs();
    904       dispatch(QualType(T.getTypePtr(), 0));
    905       pop();
    906       return;
    907     }
    908 
    909     Type *Ty = const_cast<Type*>(T.getTypePtr());
    910     push(getTypeKindName(Ty));
    911     XMLTypeVisitor<XMLDumper>::dispatch(const_cast<Type*>(T.getTypePtr()));
    912     pop();
    913   }
    914 
    915   void setCallingConv(CallingConv CC) {
    916     switch (CC) {
    917     case CC_Default: return;
    918     case CC_C: return set("cc", "cdecl");
    919     case CC_X86FastCall: return set("cc", "x86_fastcall");
    920     case CC_X86StdCall: return set("cc", "x86_stdcall");
    921     case CC_X86ThisCall: return set("cc", "x86_thiscall");
    922     case CC_X86Pascal: return set("cc", "x86_pascal");
    923     case CC_AAPCS: return set("cc", "aapcs");
    924     case CC_AAPCS_VFP: return set("cc", "aapcs_vfp");
    925     }
    926   }
    927 
    928   void visitTypeAttrs(Type *D) {
    929     setPointer(D);
    930     setFlag("dependent", D->isDependentType());
    931     setFlag("variably_modified", D->isVariablyModifiedType());
    932 
    933     setPointer("canonical", D->getCanonicalTypeInternal().getAsOpaquePtr());
    934   }
    935 
    936   void visitPointerTypeChildren(PointerType *T) {
    937     dispatch(T->getPointeeType());
    938   }
    939   void visitReferenceTypeChildren(ReferenceType *T) {
    940     dispatch(T->getPointeeType());
    941   }
    942   void visitObjCObjectPointerTypeChildren(ObjCObjectPointerType *T) {
    943     dispatch(T->getPointeeType());
    944   }
    945   void visitBlockPointerTypeChildren(BlockPointerType *T) {
    946     dispatch(T->getPointeeType());
    947   }
    948 
    949   // Types that just wrap declarations.
    950   void visitTagTypeChildren(TagType *T) {
    951     visitDeclRef(T->getDecl());
    952   }
    953   void visitTypedefTypeChildren(TypedefType *T) {
    954     visitDeclRef(T->getDecl());
    955   }
    956   void visitObjCInterfaceTypeChildren(ObjCInterfaceType *T) {
    957     visitDeclRef(T->getDecl());
    958   }
    959   void visitUnresolvedUsingTypeChildren(UnresolvedUsingType *T) {
    960     visitDeclRef(T->getDecl());
    961   }
    962   void visitInjectedClassNameTypeChildren(InjectedClassNameType *T) {
    963     visitDeclRef(T->getDecl());
    964   }
    965 
    966   void visitFunctionTypeAttrs(FunctionType *T) {
    967     setFlag("noreturn", T->getNoReturnAttr());
    968     setCallingConv(T->getCallConv());
    969     if (T->getHasRegParm()) setInteger("regparm", T->getRegParmType());
    970   }
    971   void visitFunctionTypeChildren(FunctionType *T) {
    972     dispatch(T->getResultType());
    973   }
    974 
    975   void visitFunctionProtoTypeAttrs(FunctionProtoType *T) {
    976     setFlag("const", T->getTypeQuals() & Qualifiers::Const);
    977     setFlag("volatile", T->getTypeQuals() & Qualifiers::Volatile);
    978     setFlag("restrict", T->getTypeQuals() & Qualifiers::Restrict);
    979   }
    980   void visitFunctionProtoTypeChildren(FunctionProtoType *T) {
    981     push("parameters");
    982     setFlag("variadic", T->isVariadic());
    983     completeAttrs();
    984     for (FunctionProtoType::arg_type_iterator
    985            I = T->arg_type_begin(), E = T->arg_type_end(); I != E; ++I)
    986       dispatch(*I);
    987     pop();
    988 
    989     if (T->hasDynamicExceptionSpec()) {
    990       push("exception_specifiers");
    991       setFlag("any", T->getExceptionSpecType() == EST_MSAny);
    992       completeAttrs();
    993       for (FunctionProtoType::exception_iterator
    994              I = T->exception_begin(), E = T->exception_end(); I != E; ++I)
    995         dispatch(*I);
    996       pop();
    997     }
    998     // FIXME: noexcept specifier
    999   }
   1000 
   1001   void visitTemplateSpecializationTypeChildren(TemplateSpecializationType *T) {
   1002     if (const RecordType *RT = T->getAs<RecordType>())
   1003       visitDeclRef(RT->getDecl());
   1004 
   1005     // TODO: TemplateName
   1006 
   1007     push("template_arguments");
   1008     completeAttrs();
   1009     for (unsigned I = 0, E = T->getNumArgs(); I != E; ++I)
   1010       dispatch(T->getArg(I));
   1011     pop();
   1012   }
   1013 
   1014   //---- Statements ------------------------------------------------//
   1015   void dispatch(Stmt *S) {
   1016     // FIXME: this is not really XML at all
   1017     push("Stmt");
   1018     out << ">\n";
   1019     Stack.back().State = NS_Children; // explicitly become non-lazy
   1020     S->dump(out, Context.getSourceManager());
   1021     out << '\n';
   1022     pop();
   1023   }
   1024 };
   1025 }
   1026 
   1027 void Decl::dumpXML() const {
   1028   dumpXML(llvm::errs());
   1029 }
   1030 
   1031 void Decl::dumpXML(raw_ostream &out) const {
   1032   XMLDumper(out, getASTContext()).dispatch(const_cast<Decl*>(this));
   1033 }
   1034 
   1035 #else /* ifndef NDEBUG */
   1036 
   1037 void Decl::dumpXML() const {}
   1038 void Decl::dumpXML(raw_ostream &out) const {}
   1039 
   1040 #endif
   1041