TextNodeDumper.cpp 32 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198
  1. //===--- TextNodeDumper.cpp - Printing of AST nodes -----------------------===//
  2. //
  3. // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
  4. // See https://llvm.org/LICENSE.txt for license information.
  5. // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
  6. //
  7. //===----------------------------------------------------------------------===//
  8. //
  9. // This file implements AST dumping of components of individual AST nodes.
  10. //
  11. //===----------------------------------------------------------------------===//
  12. #include "clang/AST/TextNodeDumper.h"
  13. #include "clang/AST/DeclFriend.h"
  14. #include "clang/AST/DeclOpenMP.h"
  15. #include "clang/AST/DeclTemplate.h"
  16. #include "clang/AST/LocInfoType.h"
  17. using namespace clang;
  18. static void dumpPreviousDeclImpl(raw_ostream &OS, ...) {}
  19. template <typename T>
  20. static void dumpPreviousDeclImpl(raw_ostream &OS, const Mergeable<T> *D) {
  21. const T *First = D->getFirstDecl();
  22. if (First != D)
  23. OS << " first " << First;
  24. }
  25. template <typename T>
  26. static void dumpPreviousDeclImpl(raw_ostream &OS, const Redeclarable<T> *D) {
  27. const T *Prev = D->getPreviousDecl();
  28. if (Prev)
  29. OS << " prev " << Prev;
  30. }
  31. /// Dump the previous declaration in the redeclaration chain for a declaration,
  32. /// if any.
  33. static void dumpPreviousDecl(raw_ostream &OS, const Decl *D) {
  34. switch (D->getKind()) {
  35. #define DECL(DERIVED, BASE) \
  36. case Decl::DERIVED: \
  37. return dumpPreviousDeclImpl(OS, cast<DERIVED##Decl>(D));
  38. #define ABSTRACT_DECL(DECL)
  39. #include "clang/AST/DeclNodes.inc"
  40. }
  41. llvm_unreachable("Decl that isn't part of DeclNodes.inc!");
  42. }
  43. TextNodeDumper::TextNodeDumper(raw_ostream &OS, bool ShowColors,
  44. const SourceManager *SM,
  45. const PrintingPolicy &PrintPolicy,
  46. const comments::CommandTraits *Traits)
  47. : TextTreeStructure(OS, ShowColors), OS(OS), ShowColors(ShowColors), SM(SM),
  48. PrintPolicy(PrintPolicy), Traits(Traits) {}
  49. void TextNodeDumper::Visit(const comments::Comment *C,
  50. const comments::FullComment *FC) {
  51. if (!C) {
  52. ColorScope Color(OS, ShowColors, NullColor);
  53. OS << "<<<NULL>>>";
  54. return;
  55. }
  56. {
  57. ColorScope Color(OS, ShowColors, CommentColor);
  58. OS << C->getCommentKindName();
  59. }
  60. dumpPointer(C);
  61. dumpSourceRange(C->getSourceRange());
  62. ConstCommentVisitor<TextNodeDumper, void,
  63. const comments::FullComment *>::visit(C, FC);
  64. }
  65. void TextNodeDumper::Visit(const Attr *A) {
  66. {
  67. ColorScope Color(OS, ShowColors, AttrColor);
  68. switch (A->getKind()) {
  69. #define ATTR(X) \
  70. case attr::X: \
  71. OS << #X; \
  72. break;
  73. #include "clang/Basic/AttrList.inc"
  74. }
  75. OS << "Attr";
  76. }
  77. dumpPointer(A);
  78. dumpSourceRange(A->getRange());
  79. if (A->isInherited())
  80. OS << " Inherited";
  81. if (A->isImplicit())
  82. OS << " Implicit";
  83. ConstAttrVisitor<TextNodeDumper>::Visit(A);
  84. }
  85. void TextNodeDumper::Visit(const TemplateArgument &TA, SourceRange R,
  86. const Decl *From, StringRef Label) {
  87. OS << "TemplateArgument";
  88. if (R.isValid())
  89. dumpSourceRange(R);
  90. if (From)
  91. dumpDeclRef(From, Label);
  92. ConstTemplateArgumentVisitor<TextNodeDumper>::Visit(TA);
  93. }
  94. void TextNodeDumper::Visit(const Stmt *Node) {
  95. if (!Node) {
  96. ColorScope Color(OS, ShowColors, NullColor);
  97. OS << "<<<NULL>>>";
  98. return;
  99. }
  100. {
  101. ColorScope Color(OS, ShowColors, StmtColor);
  102. OS << Node->getStmtClassName();
  103. }
  104. dumpPointer(Node);
  105. dumpSourceRange(Node->getSourceRange());
  106. if (const auto *E = dyn_cast<Expr>(Node)) {
  107. dumpType(E->getType());
  108. {
  109. ColorScope Color(OS, ShowColors, ValueKindColor);
  110. switch (E->getValueKind()) {
  111. case VK_RValue:
  112. break;
  113. case VK_LValue:
  114. OS << " lvalue";
  115. break;
  116. case VK_XValue:
  117. OS << " xvalue";
  118. break;
  119. }
  120. }
  121. {
  122. ColorScope Color(OS, ShowColors, ObjectKindColor);
  123. switch (E->getObjectKind()) {
  124. case OK_Ordinary:
  125. break;
  126. case OK_BitField:
  127. OS << " bitfield";
  128. break;
  129. case OK_ObjCProperty:
  130. OS << " objcproperty";
  131. break;
  132. case OK_ObjCSubscript:
  133. OS << " objcsubscript";
  134. break;
  135. case OK_VectorComponent:
  136. OS << " vectorcomponent";
  137. break;
  138. }
  139. }
  140. }
  141. ConstStmtVisitor<TextNodeDumper>::Visit(Node);
  142. }
  143. void TextNodeDumper::Visit(const Type *T) {
  144. if (!T) {
  145. ColorScope Color(OS, ShowColors, NullColor);
  146. OS << "<<<NULL>>>";
  147. return;
  148. }
  149. if (isa<LocInfoType>(T)) {
  150. {
  151. ColorScope Color(OS, ShowColors, TypeColor);
  152. OS << "LocInfo Type";
  153. }
  154. dumpPointer(T);
  155. return;
  156. }
  157. {
  158. ColorScope Color(OS, ShowColors, TypeColor);
  159. OS << T->getTypeClassName() << "Type";
  160. }
  161. dumpPointer(T);
  162. OS << " ";
  163. dumpBareType(QualType(T, 0), false);
  164. QualType SingleStepDesugar =
  165. T->getLocallyUnqualifiedSingleStepDesugaredType();
  166. if (SingleStepDesugar != QualType(T, 0))
  167. OS << " sugar";
  168. if (T->isDependentType())
  169. OS << " dependent";
  170. else if (T->isInstantiationDependentType())
  171. OS << " instantiation_dependent";
  172. if (T->isVariablyModifiedType())
  173. OS << " variably_modified";
  174. if (T->containsUnexpandedParameterPack())
  175. OS << " contains_unexpanded_pack";
  176. if (T->isFromAST())
  177. OS << " imported";
  178. TypeVisitor<TextNodeDumper>::Visit(T);
  179. }
  180. void TextNodeDumper::Visit(QualType T) {
  181. OS << "QualType";
  182. dumpPointer(T.getAsOpaquePtr());
  183. OS << " ";
  184. dumpBareType(T, false);
  185. OS << " " << T.split().Quals.getAsString();
  186. }
  187. void TextNodeDumper::Visit(const Decl *D) {
  188. if (!D) {
  189. ColorScope Color(OS, ShowColors, NullColor);
  190. OS << "<<<NULL>>>";
  191. return;
  192. }
  193. {
  194. ColorScope Color(OS, ShowColors, DeclKindNameColor);
  195. OS << D->getDeclKindName() << "Decl";
  196. }
  197. dumpPointer(D);
  198. if (D->getLexicalDeclContext() != D->getDeclContext())
  199. OS << " parent " << cast<Decl>(D->getDeclContext());
  200. dumpPreviousDecl(OS, D);
  201. dumpSourceRange(D->getSourceRange());
  202. OS << ' ';
  203. dumpLocation(D->getLocation());
  204. if (D->isFromASTFile())
  205. OS << " imported";
  206. if (Module *M = D->getOwningModule())
  207. OS << " in " << M->getFullModuleName();
  208. if (auto *ND = dyn_cast<NamedDecl>(D))
  209. for (Module *M : D->getASTContext().getModulesWithMergedDefinition(
  210. const_cast<NamedDecl *>(ND)))
  211. AddChild([=] { OS << "also in " << M->getFullModuleName(); });
  212. if (const NamedDecl *ND = dyn_cast<NamedDecl>(D))
  213. if (ND->isHidden())
  214. OS << " hidden";
  215. if (D->isImplicit())
  216. OS << " implicit";
  217. if (D->isUsed())
  218. OS << " used";
  219. else if (D->isThisDeclarationReferenced())
  220. OS << " referenced";
  221. if (D->isInvalidDecl())
  222. OS << " invalid";
  223. if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(D))
  224. if (FD->isConstexpr())
  225. OS << " constexpr";
  226. if (!isa<FunctionDecl>(*D)) {
  227. const auto *MD = dyn_cast<ObjCMethodDecl>(D);
  228. if (!MD || !MD->isThisDeclarationADefinition()) {
  229. const auto *DC = dyn_cast<DeclContext>(D);
  230. if (DC && DC->hasExternalLexicalStorage()) {
  231. ColorScope Color(OS, ShowColors, UndeserializedColor);
  232. OS << " <undeserialized declarations>";
  233. }
  234. }
  235. }
  236. }
  237. void TextNodeDumper::Visit(const CXXCtorInitializer *Init) {
  238. OS << "CXXCtorInitializer";
  239. if (Init->isAnyMemberInitializer()) {
  240. OS << ' ';
  241. dumpBareDeclRef(Init->getAnyMember());
  242. } else if (Init->isBaseInitializer()) {
  243. dumpType(QualType(Init->getBaseClass(), 0));
  244. } else if (Init->isDelegatingInitializer()) {
  245. dumpType(Init->getTypeSourceInfo()->getType());
  246. } else {
  247. llvm_unreachable("Unknown initializer type");
  248. }
  249. }
  250. void TextNodeDumper::Visit(const BlockDecl::Capture &C) {
  251. OS << "capture";
  252. if (C.isByRef())
  253. OS << " byref";
  254. if (C.isNested())
  255. OS << " nested";
  256. if (C.getVariable()) {
  257. OS << ' ';
  258. dumpBareDeclRef(C.getVariable());
  259. }
  260. }
  261. void TextNodeDumper::Visit(const OMPClause *C) {
  262. if (!C) {
  263. ColorScope Color(OS, ShowColors, NullColor);
  264. OS << "<<<NULL>>> OMPClause";
  265. return;
  266. }
  267. {
  268. ColorScope Color(OS, ShowColors, AttrColor);
  269. StringRef ClauseName(getOpenMPClauseName(C->getClauseKind()));
  270. OS << "OMP" << ClauseName.substr(/*Start=*/0, /*N=*/1).upper()
  271. << ClauseName.drop_front() << "Clause";
  272. }
  273. dumpPointer(C);
  274. dumpSourceRange(SourceRange(C->getBeginLoc(), C->getEndLoc()));
  275. if (C->isImplicit())
  276. OS << " <implicit>";
  277. }
  278. void TextNodeDumper::Visit(const GenericSelectionExpr::ConstAssociation &A) {
  279. const TypeSourceInfo *TSI = A.getTypeSourceInfo();
  280. if (TSI) {
  281. OS << "case ";
  282. dumpType(TSI->getType());
  283. } else {
  284. OS << "default";
  285. }
  286. if (A.isSelected())
  287. OS << " selected";
  288. }
  289. void TextNodeDumper::dumpPointer(const void *Ptr) {
  290. ColorScope Color(OS, ShowColors, AddressColor);
  291. OS << ' ' << Ptr;
  292. }
  293. void TextNodeDumper::dumpLocation(SourceLocation Loc) {
  294. if (!SM)
  295. return;
  296. ColorScope Color(OS, ShowColors, LocationColor);
  297. SourceLocation SpellingLoc = SM->getSpellingLoc(Loc);
  298. // The general format we print out is filename:line:col, but we drop pieces
  299. // that haven't changed since the last loc printed.
  300. PresumedLoc PLoc = SM->getPresumedLoc(SpellingLoc);
  301. if (PLoc.isInvalid()) {
  302. OS << "<invalid sloc>";
  303. return;
  304. }
  305. if (strcmp(PLoc.getFilename(), LastLocFilename) != 0) {
  306. OS << PLoc.getFilename() << ':' << PLoc.getLine() << ':'
  307. << PLoc.getColumn();
  308. LastLocFilename = PLoc.getFilename();
  309. LastLocLine = PLoc.getLine();
  310. } else if (PLoc.getLine() != LastLocLine) {
  311. OS << "line" << ':' << PLoc.getLine() << ':' << PLoc.getColumn();
  312. LastLocLine = PLoc.getLine();
  313. } else {
  314. OS << "col" << ':' << PLoc.getColumn();
  315. }
  316. }
  317. void TextNodeDumper::dumpSourceRange(SourceRange R) {
  318. // Can't translate locations if a SourceManager isn't available.
  319. if (!SM)
  320. return;
  321. OS << " <";
  322. dumpLocation(R.getBegin());
  323. if (R.getBegin() != R.getEnd()) {
  324. OS << ", ";
  325. dumpLocation(R.getEnd());
  326. }
  327. OS << ">";
  328. // <t2.c:123:421[blah], t2.c:412:321>
  329. }
  330. void TextNodeDumper::dumpBareType(QualType T, bool Desugar) {
  331. ColorScope Color(OS, ShowColors, TypeColor);
  332. SplitQualType T_split = T.split();
  333. OS << "'" << QualType::getAsString(T_split, PrintPolicy) << "'";
  334. if (Desugar && !T.isNull()) {
  335. // If the type is sugared, also dump a (shallow) desugared type.
  336. SplitQualType D_split = T.getSplitDesugaredType();
  337. if (T_split != D_split)
  338. OS << ":'" << QualType::getAsString(D_split, PrintPolicy) << "'";
  339. }
  340. }
  341. void TextNodeDumper::dumpType(QualType T) {
  342. OS << ' ';
  343. dumpBareType(T);
  344. }
  345. void TextNodeDumper::dumpBareDeclRef(const Decl *D) {
  346. if (!D) {
  347. ColorScope Color(OS, ShowColors, NullColor);
  348. OS << "<<<NULL>>>";
  349. return;
  350. }
  351. {
  352. ColorScope Color(OS, ShowColors, DeclKindNameColor);
  353. OS << D->getDeclKindName();
  354. }
  355. dumpPointer(D);
  356. if (const NamedDecl *ND = dyn_cast<NamedDecl>(D)) {
  357. ColorScope Color(OS, ShowColors, DeclNameColor);
  358. OS << " '" << ND->getDeclName() << '\'';
  359. }
  360. if (const ValueDecl *VD = dyn_cast<ValueDecl>(D))
  361. dumpType(VD->getType());
  362. }
  363. void TextNodeDumper::dumpName(const NamedDecl *ND) {
  364. if (ND->getDeclName()) {
  365. ColorScope Color(OS, ShowColors, DeclNameColor);
  366. OS << ' ' << ND->getNameAsString();
  367. }
  368. }
  369. void TextNodeDumper::dumpAccessSpecifier(AccessSpecifier AS) {
  370. switch (AS) {
  371. case AS_none:
  372. break;
  373. case AS_public:
  374. OS << "public";
  375. break;
  376. case AS_protected:
  377. OS << "protected";
  378. break;
  379. case AS_private:
  380. OS << "private";
  381. break;
  382. }
  383. }
  384. void TextNodeDumper::dumpCXXTemporary(const CXXTemporary *Temporary) {
  385. OS << "(CXXTemporary";
  386. dumpPointer(Temporary);
  387. OS << ")";
  388. }
  389. void TextNodeDumper::dumpDeclRef(const Decl *D, StringRef Label) {
  390. if (!D)
  391. return;
  392. AddChild([=] {
  393. if (!Label.empty())
  394. OS << Label << ' ';
  395. dumpBareDeclRef(D);
  396. });
  397. }
  398. const char *TextNodeDumper::getCommandName(unsigned CommandID) {
  399. if (Traits)
  400. return Traits->getCommandInfo(CommandID)->Name;
  401. const comments::CommandInfo *Info =
  402. comments::CommandTraits::getBuiltinCommandInfo(CommandID);
  403. if (Info)
  404. return Info->Name;
  405. return "<not a builtin command>";
  406. }
  407. void TextNodeDumper::visitTextComment(const comments::TextComment *C,
  408. const comments::FullComment *) {
  409. OS << " Text=\"" << C->getText() << "\"";
  410. }
  411. void TextNodeDumper::visitInlineCommandComment(
  412. const comments::InlineCommandComment *C, const comments::FullComment *) {
  413. OS << " Name=\"" << getCommandName(C->getCommandID()) << "\"";
  414. switch (C->getRenderKind()) {
  415. case comments::InlineCommandComment::RenderNormal:
  416. OS << " RenderNormal";
  417. break;
  418. case comments::InlineCommandComment::RenderBold:
  419. OS << " RenderBold";
  420. break;
  421. case comments::InlineCommandComment::RenderMonospaced:
  422. OS << " RenderMonospaced";
  423. break;
  424. case comments::InlineCommandComment::RenderEmphasized:
  425. OS << " RenderEmphasized";
  426. break;
  427. }
  428. for (unsigned i = 0, e = C->getNumArgs(); i != e; ++i)
  429. OS << " Arg[" << i << "]=\"" << C->getArgText(i) << "\"";
  430. }
  431. void TextNodeDumper::visitHTMLStartTagComment(
  432. const comments::HTMLStartTagComment *C, const comments::FullComment *) {
  433. OS << " Name=\"" << C->getTagName() << "\"";
  434. if (C->getNumAttrs() != 0) {
  435. OS << " Attrs: ";
  436. for (unsigned i = 0, e = C->getNumAttrs(); i != e; ++i) {
  437. const comments::HTMLStartTagComment::Attribute &Attr = C->getAttr(i);
  438. OS << " \"" << Attr.Name << "=\"" << Attr.Value << "\"";
  439. }
  440. }
  441. if (C->isSelfClosing())
  442. OS << " SelfClosing";
  443. }
  444. void TextNodeDumper::visitHTMLEndTagComment(
  445. const comments::HTMLEndTagComment *C, const comments::FullComment *) {
  446. OS << " Name=\"" << C->getTagName() << "\"";
  447. }
  448. void TextNodeDumper::visitBlockCommandComment(
  449. const comments::BlockCommandComment *C, const comments::FullComment *) {
  450. OS << " Name=\"" << getCommandName(C->getCommandID()) << "\"";
  451. for (unsigned i = 0, e = C->getNumArgs(); i != e; ++i)
  452. OS << " Arg[" << i << "]=\"" << C->getArgText(i) << "\"";
  453. }
  454. void TextNodeDumper::visitParamCommandComment(
  455. const comments::ParamCommandComment *C, const comments::FullComment *FC) {
  456. OS << " "
  457. << comments::ParamCommandComment::getDirectionAsString(C->getDirection());
  458. if (C->isDirectionExplicit())
  459. OS << " explicitly";
  460. else
  461. OS << " implicitly";
  462. if (C->hasParamName()) {
  463. if (C->isParamIndexValid())
  464. OS << " Param=\"" << C->getParamName(FC) << "\"";
  465. else
  466. OS << " Param=\"" << C->getParamNameAsWritten() << "\"";
  467. }
  468. if (C->isParamIndexValid() && !C->isVarArgParam())
  469. OS << " ParamIndex=" << C->getParamIndex();
  470. }
  471. void TextNodeDumper::visitTParamCommandComment(
  472. const comments::TParamCommandComment *C, const comments::FullComment *FC) {
  473. if (C->hasParamName()) {
  474. if (C->isPositionValid())
  475. OS << " Param=\"" << C->getParamName(FC) << "\"";
  476. else
  477. OS << " Param=\"" << C->getParamNameAsWritten() << "\"";
  478. }
  479. if (C->isPositionValid()) {
  480. OS << " Position=<";
  481. for (unsigned i = 0, e = C->getDepth(); i != e; ++i) {
  482. OS << C->getIndex(i);
  483. if (i != e - 1)
  484. OS << ", ";
  485. }
  486. OS << ">";
  487. }
  488. }
  489. void TextNodeDumper::visitVerbatimBlockComment(
  490. const comments::VerbatimBlockComment *C, const comments::FullComment *) {
  491. OS << " Name=\"" << getCommandName(C->getCommandID())
  492. << "\""
  493. " CloseName=\""
  494. << C->getCloseName() << "\"";
  495. }
  496. void TextNodeDumper::visitVerbatimBlockLineComment(
  497. const comments::VerbatimBlockLineComment *C,
  498. const comments::FullComment *) {
  499. OS << " Text=\"" << C->getText() << "\"";
  500. }
  501. void TextNodeDumper::visitVerbatimLineComment(
  502. const comments::VerbatimLineComment *C, const comments::FullComment *) {
  503. OS << " Text=\"" << C->getText() << "\"";
  504. }
  505. void TextNodeDumper::VisitNullTemplateArgument(const TemplateArgument &) {
  506. OS << " null";
  507. }
  508. void TextNodeDumper::VisitTypeTemplateArgument(const TemplateArgument &TA) {
  509. OS << " type";
  510. dumpType(TA.getAsType());
  511. }
  512. void TextNodeDumper::VisitDeclarationTemplateArgument(
  513. const TemplateArgument &TA) {
  514. OS << " decl";
  515. dumpDeclRef(TA.getAsDecl());
  516. }
  517. void TextNodeDumper::VisitNullPtrTemplateArgument(const TemplateArgument &) {
  518. OS << " nullptr";
  519. }
  520. void TextNodeDumper::VisitIntegralTemplateArgument(const TemplateArgument &TA) {
  521. OS << " integral " << TA.getAsIntegral();
  522. }
  523. void TextNodeDumper::VisitTemplateTemplateArgument(const TemplateArgument &TA) {
  524. OS << " template ";
  525. TA.getAsTemplate().dump(OS);
  526. }
  527. void TextNodeDumper::VisitTemplateExpansionTemplateArgument(
  528. const TemplateArgument &TA) {
  529. OS << " template expansion ";
  530. TA.getAsTemplateOrTemplatePattern().dump(OS);
  531. }
  532. void TextNodeDumper::VisitExpressionTemplateArgument(const TemplateArgument &) {
  533. OS << " expr";
  534. }
  535. void TextNodeDumper::VisitPackTemplateArgument(const TemplateArgument &) {
  536. OS << " pack";
  537. }
  538. static void dumpBasePath(raw_ostream &OS, const CastExpr *Node) {
  539. if (Node->path_empty())
  540. return;
  541. OS << " (";
  542. bool First = true;
  543. for (CastExpr::path_const_iterator I = Node->path_begin(),
  544. E = Node->path_end();
  545. I != E; ++I) {
  546. const CXXBaseSpecifier *Base = *I;
  547. if (!First)
  548. OS << " -> ";
  549. const CXXRecordDecl *RD =
  550. cast<CXXRecordDecl>(Base->getType()->getAs<RecordType>()->getDecl());
  551. if (Base->isVirtual())
  552. OS << "virtual ";
  553. OS << RD->getName();
  554. First = false;
  555. }
  556. OS << ')';
  557. }
  558. void TextNodeDumper::VisitIfStmt(const IfStmt *Node) {
  559. if (Node->hasInitStorage())
  560. OS << " has_init";
  561. if (Node->hasVarStorage())
  562. OS << " has_var";
  563. if (Node->hasElseStorage())
  564. OS << " has_else";
  565. }
  566. void TextNodeDumper::VisitSwitchStmt(const SwitchStmt *Node) {
  567. if (Node->hasInitStorage())
  568. OS << " has_init";
  569. if (Node->hasVarStorage())
  570. OS << " has_var";
  571. }
  572. void TextNodeDumper::VisitWhileStmt(const WhileStmt *Node) {
  573. if (Node->hasVarStorage())
  574. OS << " has_var";
  575. }
  576. void TextNodeDumper::VisitLabelStmt(const LabelStmt *Node) {
  577. OS << " '" << Node->getName() << "'";
  578. }
  579. void TextNodeDumper::VisitGotoStmt(const GotoStmt *Node) {
  580. OS << " '" << Node->getLabel()->getName() << "'";
  581. dumpPointer(Node->getLabel());
  582. }
  583. void TextNodeDumper::VisitCaseStmt(const CaseStmt *Node) {
  584. if (Node->caseStmtIsGNURange())
  585. OS << " gnu_range";
  586. }
  587. void TextNodeDumper::VisitCallExpr(const CallExpr *Node) {
  588. if (Node->usesADL())
  589. OS << " adl";
  590. }
  591. void TextNodeDumper::VisitCastExpr(const CastExpr *Node) {
  592. OS << " <";
  593. {
  594. ColorScope Color(OS, ShowColors, CastColor);
  595. OS << Node->getCastKindName();
  596. }
  597. dumpBasePath(OS, Node);
  598. OS << ">";
  599. }
  600. void TextNodeDumper::VisitImplicitCastExpr(const ImplicitCastExpr *Node) {
  601. VisitCastExpr(Node);
  602. if (Node->isPartOfExplicitCast())
  603. OS << " part_of_explicit_cast";
  604. }
  605. void TextNodeDumper::VisitDeclRefExpr(const DeclRefExpr *Node) {
  606. OS << " ";
  607. dumpBareDeclRef(Node->getDecl());
  608. if (Node->getDecl() != Node->getFoundDecl()) {
  609. OS << " (";
  610. dumpBareDeclRef(Node->getFoundDecl());
  611. OS << ")";
  612. }
  613. }
  614. void TextNodeDumper::VisitUnresolvedLookupExpr(
  615. const UnresolvedLookupExpr *Node) {
  616. OS << " (";
  617. if (!Node->requiresADL())
  618. OS << "no ";
  619. OS << "ADL) = '" << Node->getName() << '\'';
  620. UnresolvedLookupExpr::decls_iterator I = Node->decls_begin(),
  621. E = Node->decls_end();
  622. if (I == E)
  623. OS << " empty";
  624. for (; I != E; ++I)
  625. dumpPointer(*I);
  626. }
  627. void TextNodeDumper::VisitObjCIvarRefExpr(const ObjCIvarRefExpr *Node) {
  628. {
  629. ColorScope Color(OS, ShowColors, DeclKindNameColor);
  630. OS << " " << Node->getDecl()->getDeclKindName() << "Decl";
  631. }
  632. OS << "='" << *Node->getDecl() << "'";
  633. dumpPointer(Node->getDecl());
  634. if (Node->isFreeIvar())
  635. OS << " isFreeIvar";
  636. }
  637. void TextNodeDumper::VisitPredefinedExpr(const PredefinedExpr *Node) {
  638. OS << " " << PredefinedExpr::getIdentKindName(Node->getIdentKind());
  639. }
  640. void TextNodeDumper::VisitCharacterLiteral(const CharacterLiteral *Node) {
  641. ColorScope Color(OS, ShowColors, ValueColor);
  642. OS << " " << Node->getValue();
  643. }
  644. void TextNodeDumper::VisitIntegerLiteral(const IntegerLiteral *Node) {
  645. bool isSigned = Node->getType()->isSignedIntegerType();
  646. ColorScope Color(OS, ShowColors, ValueColor);
  647. OS << " " << Node->getValue().toString(10, isSigned);
  648. }
  649. void TextNodeDumper::VisitFixedPointLiteral(const FixedPointLiteral *Node) {
  650. ColorScope Color(OS, ShowColors, ValueColor);
  651. OS << " " << Node->getValueAsString(/*Radix=*/10);
  652. }
  653. void TextNodeDumper::VisitFloatingLiteral(const FloatingLiteral *Node) {
  654. ColorScope Color(OS, ShowColors, ValueColor);
  655. OS << " " << Node->getValueAsApproximateDouble();
  656. }
  657. void TextNodeDumper::VisitStringLiteral(const StringLiteral *Str) {
  658. ColorScope Color(OS, ShowColors, ValueColor);
  659. OS << " ";
  660. Str->outputString(OS);
  661. }
  662. void TextNodeDumper::VisitInitListExpr(const InitListExpr *ILE) {
  663. if (auto *Field = ILE->getInitializedFieldInUnion()) {
  664. OS << " field ";
  665. dumpBareDeclRef(Field);
  666. }
  667. }
  668. void TextNodeDumper::VisitGenericSelectionExpr(const GenericSelectionExpr *E) {
  669. if (E->isResultDependent())
  670. OS << " result_dependent";
  671. }
  672. void TextNodeDumper::VisitUnaryOperator(const UnaryOperator *Node) {
  673. OS << " " << (Node->isPostfix() ? "postfix" : "prefix") << " '"
  674. << UnaryOperator::getOpcodeStr(Node->getOpcode()) << "'";
  675. if (!Node->canOverflow())
  676. OS << " cannot overflow";
  677. }
  678. void TextNodeDumper::VisitUnaryExprOrTypeTraitExpr(
  679. const UnaryExprOrTypeTraitExpr *Node) {
  680. switch (Node->getKind()) {
  681. case UETT_SizeOf:
  682. OS << " sizeof";
  683. break;
  684. case UETT_AlignOf:
  685. OS << " alignof";
  686. break;
  687. case UETT_VecStep:
  688. OS << " vec_step";
  689. break;
  690. case UETT_OpenMPRequiredSimdAlign:
  691. OS << " __builtin_omp_required_simd_align";
  692. break;
  693. case UETT_PreferredAlignOf:
  694. OS << " __alignof";
  695. break;
  696. }
  697. if (Node->isArgumentType())
  698. dumpType(Node->getArgumentType());
  699. }
  700. void TextNodeDumper::VisitMemberExpr(const MemberExpr *Node) {
  701. OS << " " << (Node->isArrow() ? "->" : ".") << *Node->getMemberDecl();
  702. dumpPointer(Node->getMemberDecl());
  703. }
  704. void TextNodeDumper::VisitExtVectorElementExpr(
  705. const ExtVectorElementExpr *Node) {
  706. OS << " " << Node->getAccessor().getNameStart();
  707. }
  708. void TextNodeDumper::VisitBinaryOperator(const BinaryOperator *Node) {
  709. OS << " '" << BinaryOperator::getOpcodeStr(Node->getOpcode()) << "'";
  710. }
  711. void TextNodeDumper::VisitCompoundAssignOperator(
  712. const CompoundAssignOperator *Node) {
  713. OS << " '" << BinaryOperator::getOpcodeStr(Node->getOpcode())
  714. << "' ComputeLHSTy=";
  715. dumpBareType(Node->getComputationLHSType());
  716. OS << " ComputeResultTy=";
  717. dumpBareType(Node->getComputationResultType());
  718. }
  719. void TextNodeDumper::VisitAddrLabelExpr(const AddrLabelExpr *Node) {
  720. OS << " " << Node->getLabel()->getName();
  721. dumpPointer(Node->getLabel());
  722. }
  723. void TextNodeDumper::VisitCXXNamedCastExpr(const CXXNamedCastExpr *Node) {
  724. OS << " " << Node->getCastName() << "<"
  725. << Node->getTypeAsWritten().getAsString() << ">"
  726. << " <" << Node->getCastKindName();
  727. dumpBasePath(OS, Node);
  728. OS << ">";
  729. }
  730. void TextNodeDumper::VisitCXXBoolLiteralExpr(const CXXBoolLiteralExpr *Node) {
  731. OS << " " << (Node->getValue() ? "true" : "false");
  732. }
  733. void TextNodeDumper::VisitCXXThisExpr(const CXXThisExpr *Node) {
  734. OS << " this";
  735. }
  736. void TextNodeDumper::VisitCXXFunctionalCastExpr(
  737. const CXXFunctionalCastExpr *Node) {
  738. OS << " functional cast to " << Node->getTypeAsWritten().getAsString() << " <"
  739. << Node->getCastKindName() << ">";
  740. }
  741. void TextNodeDumper::VisitCXXUnresolvedConstructExpr(
  742. const CXXUnresolvedConstructExpr *Node) {
  743. dumpType(Node->getTypeAsWritten());
  744. if (Node->isListInitialization())
  745. OS << " list";
  746. }
  747. void TextNodeDumper::VisitCXXConstructExpr(const CXXConstructExpr *Node) {
  748. CXXConstructorDecl *Ctor = Node->getConstructor();
  749. dumpType(Ctor->getType());
  750. if (Node->isElidable())
  751. OS << " elidable";
  752. if (Node->isListInitialization())
  753. OS << " list";
  754. if (Node->isStdInitListInitialization())
  755. OS << " std::initializer_list";
  756. if (Node->requiresZeroInitialization())
  757. OS << " zeroing";
  758. }
  759. void TextNodeDumper::VisitCXXBindTemporaryExpr(
  760. const CXXBindTemporaryExpr *Node) {
  761. OS << " ";
  762. dumpCXXTemporary(Node->getTemporary());
  763. }
  764. void TextNodeDumper::VisitCXXNewExpr(const CXXNewExpr *Node) {
  765. if (Node->isGlobalNew())
  766. OS << " global";
  767. if (Node->isArray())
  768. OS << " array";
  769. if (Node->getOperatorNew()) {
  770. OS << ' ';
  771. dumpBareDeclRef(Node->getOperatorNew());
  772. }
  773. // We could dump the deallocation function used in case of error, but it's
  774. // usually not that interesting.
  775. }
  776. void TextNodeDumper::VisitCXXDeleteExpr(const CXXDeleteExpr *Node) {
  777. if (Node->isGlobalDelete())
  778. OS << " global";
  779. if (Node->isArrayForm())
  780. OS << " array";
  781. if (Node->getOperatorDelete()) {
  782. OS << ' ';
  783. dumpBareDeclRef(Node->getOperatorDelete());
  784. }
  785. }
  786. void TextNodeDumper::VisitMaterializeTemporaryExpr(
  787. const MaterializeTemporaryExpr *Node) {
  788. if (const ValueDecl *VD = Node->getExtendingDecl()) {
  789. OS << " extended by ";
  790. dumpBareDeclRef(VD);
  791. }
  792. }
  793. void TextNodeDumper::VisitExprWithCleanups(const ExprWithCleanups *Node) {
  794. for (unsigned i = 0, e = Node->getNumObjects(); i != e; ++i)
  795. dumpDeclRef(Node->getObject(i), "cleanup");
  796. }
  797. void TextNodeDumper::VisitSizeOfPackExpr(const SizeOfPackExpr *Node) {
  798. dumpPointer(Node->getPack());
  799. dumpName(Node->getPack());
  800. }
  801. void TextNodeDumper::VisitCXXDependentScopeMemberExpr(
  802. const CXXDependentScopeMemberExpr *Node) {
  803. OS << " " << (Node->isArrow() ? "->" : ".") << Node->getMember();
  804. }
  805. void TextNodeDumper::VisitObjCMessageExpr(const ObjCMessageExpr *Node) {
  806. OS << " selector=";
  807. Node->getSelector().print(OS);
  808. switch (Node->getReceiverKind()) {
  809. case ObjCMessageExpr::Instance:
  810. break;
  811. case ObjCMessageExpr::Class:
  812. OS << " class=";
  813. dumpBareType(Node->getClassReceiver());
  814. break;
  815. case ObjCMessageExpr::SuperInstance:
  816. OS << " super (instance)";
  817. break;
  818. case ObjCMessageExpr::SuperClass:
  819. OS << " super (class)";
  820. break;
  821. }
  822. }
  823. void TextNodeDumper::VisitObjCBoxedExpr(const ObjCBoxedExpr *Node) {
  824. if (auto *BoxingMethod = Node->getBoxingMethod()) {
  825. OS << " selector=";
  826. BoxingMethod->getSelector().print(OS);
  827. }
  828. }
  829. void TextNodeDumper::VisitObjCAtCatchStmt(const ObjCAtCatchStmt *Node) {
  830. if (!Node->getCatchParamDecl())
  831. OS << " catch all";
  832. }
  833. void TextNodeDumper::VisitObjCEncodeExpr(const ObjCEncodeExpr *Node) {
  834. dumpType(Node->getEncodedType());
  835. }
  836. void TextNodeDumper::VisitObjCSelectorExpr(const ObjCSelectorExpr *Node) {
  837. OS << " ";
  838. Node->getSelector().print(OS);
  839. }
  840. void TextNodeDumper::VisitObjCProtocolExpr(const ObjCProtocolExpr *Node) {
  841. OS << ' ' << *Node->getProtocol();
  842. }
  843. void TextNodeDumper::VisitObjCPropertyRefExpr(const ObjCPropertyRefExpr *Node) {
  844. if (Node->isImplicitProperty()) {
  845. OS << " Kind=MethodRef Getter=\"";
  846. if (Node->getImplicitPropertyGetter())
  847. Node->getImplicitPropertyGetter()->getSelector().print(OS);
  848. else
  849. OS << "(null)";
  850. OS << "\" Setter=\"";
  851. if (ObjCMethodDecl *Setter = Node->getImplicitPropertySetter())
  852. Setter->getSelector().print(OS);
  853. else
  854. OS << "(null)";
  855. OS << "\"";
  856. } else {
  857. OS << " Kind=PropertyRef Property=\"" << *Node->getExplicitProperty()
  858. << '"';
  859. }
  860. if (Node->isSuperReceiver())
  861. OS << " super";
  862. OS << " Messaging=";
  863. if (Node->isMessagingGetter() && Node->isMessagingSetter())
  864. OS << "Getter&Setter";
  865. else if (Node->isMessagingGetter())
  866. OS << "Getter";
  867. else if (Node->isMessagingSetter())
  868. OS << "Setter";
  869. }
  870. void TextNodeDumper::VisitObjCSubscriptRefExpr(
  871. const ObjCSubscriptRefExpr *Node) {
  872. if (Node->isArraySubscriptRefExpr())
  873. OS << " Kind=ArraySubscript GetterForArray=\"";
  874. else
  875. OS << " Kind=DictionarySubscript GetterForDictionary=\"";
  876. if (Node->getAtIndexMethodDecl())
  877. Node->getAtIndexMethodDecl()->getSelector().print(OS);
  878. else
  879. OS << "(null)";
  880. if (Node->isArraySubscriptRefExpr())
  881. OS << "\" SetterForArray=\"";
  882. else
  883. OS << "\" SetterForDictionary=\"";
  884. if (Node->setAtIndexMethodDecl())
  885. Node->setAtIndexMethodDecl()->getSelector().print(OS);
  886. else
  887. OS << "(null)";
  888. }
  889. void TextNodeDumper::VisitObjCBoolLiteralExpr(const ObjCBoolLiteralExpr *Node) {
  890. OS << " " << (Node->getValue() ? "__objc_yes" : "__objc_no");
  891. }
  892. void TextNodeDumper::VisitRValueReferenceType(const ReferenceType *T) {
  893. if (T->isSpelledAsLValue())
  894. OS << " written as lvalue reference";
  895. }
  896. void TextNodeDumper::VisitArrayType(const ArrayType *T) {
  897. switch (T->getSizeModifier()) {
  898. case ArrayType::Normal:
  899. break;
  900. case ArrayType::Static:
  901. OS << " static";
  902. break;
  903. case ArrayType::Star:
  904. OS << " *";
  905. break;
  906. }
  907. OS << " " << T->getIndexTypeQualifiers().getAsString();
  908. }
  909. void TextNodeDumper::VisitConstantArrayType(const ConstantArrayType *T) {
  910. OS << " " << T->getSize();
  911. VisitArrayType(T);
  912. }
  913. void TextNodeDumper::VisitVariableArrayType(const VariableArrayType *T) {
  914. OS << " ";
  915. dumpSourceRange(T->getBracketsRange());
  916. VisitArrayType(T);
  917. }
  918. void TextNodeDumper::VisitDependentSizedArrayType(
  919. const DependentSizedArrayType *T) {
  920. VisitArrayType(T);
  921. OS << " ";
  922. dumpSourceRange(T->getBracketsRange());
  923. }
  924. void TextNodeDumper::VisitDependentSizedExtVectorType(
  925. const DependentSizedExtVectorType *T) {
  926. OS << " ";
  927. dumpLocation(T->getAttributeLoc());
  928. }
  929. void TextNodeDumper::VisitVectorType(const VectorType *T) {
  930. switch (T->getVectorKind()) {
  931. case VectorType::GenericVector:
  932. break;
  933. case VectorType::AltiVecVector:
  934. OS << " altivec";
  935. break;
  936. case VectorType::AltiVecPixel:
  937. OS << " altivec pixel";
  938. break;
  939. case VectorType::AltiVecBool:
  940. OS << " altivec bool";
  941. break;
  942. case VectorType::NeonVector:
  943. OS << " neon";
  944. break;
  945. case VectorType::NeonPolyVector:
  946. OS << " neon poly";
  947. break;
  948. }
  949. OS << " " << T->getNumElements();
  950. }
  951. void TextNodeDumper::VisitFunctionType(const FunctionType *T) {
  952. auto EI = T->getExtInfo();
  953. if (EI.getNoReturn())
  954. OS << " noreturn";
  955. if (EI.getProducesResult())
  956. OS << " produces_result";
  957. if (EI.getHasRegParm())
  958. OS << " regparm " << EI.getRegParm();
  959. OS << " " << FunctionType::getNameForCallConv(EI.getCC());
  960. }
  961. void TextNodeDumper::VisitFunctionProtoType(const FunctionProtoType *T) {
  962. auto EPI = T->getExtProtoInfo();
  963. if (EPI.HasTrailingReturn)
  964. OS << " trailing_return";
  965. if (T->isConst())
  966. OS << " const";
  967. if (T->isVolatile())
  968. OS << " volatile";
  969. if (T->isRestrict())
  970. OS << " restrict";
  971. if (T->getExtProtoInfo().Variadic)
  972. OS << " variadic";
  973. switch (EPI.RefQualifier) {
  974. case RQ_None:
  975. break;
  976. case RQ_LValue:
  977. OS << " &";
  978. break;
  979. case RQ_RValue:
  980. OS << " &&";
  981. break;
  982. }
  983. // FIXME: Exception specification.
  984. // FIXME: Consumed parameters.
  985. VisitFunctionType(T);
  986. }
  987. void TextNodeDumper::VisitUnresolvedUsingType(const UnresolvedUsingType *T) {
  988. dumpDeclRef(T->getDecl());
  989. }
  990. void TextNodeDumper::VisitTypedefType(const TypedefType *T) {
  991. dumpDeclRef(T->getDecl());
  992. }
  993. void TextNodeDumper::VisitUnaryTransformType(const UnaryTransformType *T) {
  994. switch (T->getUTTKind()) {
  995. case UnaryTransformType::EnumUnderlyingType:
  996. OS << " underlying_type";
  997. break;
  998. }
  999. }
  1000. void TextNodeDumper::VisitTagType(const TagType *T) {
  1001. dumpDeclRef(T->getDecl());
  1002. }
  1003. void TextNodeDumper::VisitTemplateTypeParmType(const TemplateTypeParmType *T) {
  1004. OS << " depth " << T->getDepth() << " index " << T->getIndex();
  1005. if (T->isParameterPack())
  1006. OS << " pack";
  1007. dumpDeclRef(T->getDecl());
  1008. }
  1009. void TextNodeDumper::VisitAutoType(const AutoType *T) {
  1010. if (T->isDecltypeAuto())
  1011. OS << " decltype(auto)";
  1012. if (!T->isDeduced())
  1013. OS << " undeduced";
  1014. }
  1015. void TextNodeDumper::VisitTemplateSpecializationType(
  1016. const TemplateSpecializationType *T) {
  1017. if (T->isTypeAlias())
  1018. OS << " alias";
  1019. OS << " ";
  1020. T->getTemplateName().dump(OS);
  1021. }
  1022. void TextNodeDumper::VisitInjectedClassNameType(
  1023. const InjectedClassNameType *T) {
  1024. dumpDeclRef(T->getDecl());
  1025. }
  1026. void TextNodeDumper::VisitObjCInterfaceType(const ObjCInterfaceType *T) {
  1027. dumpDeclRef(T->getDecl());
  1028. }
  1029. void TextNodeDumper::VisitPackExpansionType(const PackExpansionType *T) {
  1030. if (auto N = T->getNumExpansions())
  1031. OS << " expansions " << *N;
  1032. }