DumpXML.cpp 30 KB

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