ASTConsumers.cpp 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480
  1. //===--- ASTConsumers.cpp - ASTConsumer implementations -------------------===//
  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. // AST Consumer Implementations.
  11. //
  12. //===----------------------------------------------------------------------===//
  13. #include "clang/Frontend/ASTConsumers.h"
  14. #include "clang/AST/AST.h"
  15. #include "clang/AST/ASTConsumer.h"
  16. #include "clang/AST/ASTContext.h"
  17. #include "clang/AST/PrettyPrinter.h"
  18. #include "clang/AST/RecordLayout.h"
  19. #include "clang/AST/RecursiveASTVisitor.h"
  20. #include "clang/Basic/Diagnostic.h"
  21. #include "clang/Basic/FileManager.h"
  22. #include "clang/Basic/SourceManager.h"
  23. #include "llvm/IR/Module.h"
  24. #include "llvm/Support/Path.h"
  25. #include "llvm/Support/Timer.h"
  26. #include "llvm/Support/raw_ostream.h"
  27. using namespace clang;
  28. //===----------------------------------------------------------------------===//
  29. /// ASTPrinter - Pretty-printer and dumper of ASTs
  30. namespace {
  31. class ASTPrinter : public ASTConsumer,
  32. public RecursiveASTVisitor<ASTPrinter> {
  33. typedef RecursiveASTVisitor<ASTPrinter> base;
  34. public:
  35. ASTPrinter(raw_ostream *Out = nullptr, bool Dump = false,
  36. StringRef FilterString = "", bool DumpLookups = false)
  37. : Out(Out ? *Out : llvm::outs()), Dump(Dump),
  38. FilterString(FilterString), DumpLookups(DumpLookups) {}
  39. void HandleTranslationUnit(ASTContext &Context) override {
  40. TranslationUnitDecl *D = Context.getTranslationUnitDecl();
  41. if (FilterString.empty())
  42. return print(D);
  43. TraverseDecl(D);
  44. }
  45. bool shouldWalkTypesOfTypeLocs() const { return false; }
  46. bool TraverseDecl(Decl *D) {
  47. if (D && filterMatches(D)) {
  48. bool ShowColors = Out.has_colors();
  49. if (ShowColors)
  50. Out.changeColor(raw_ostream::BLUE);
  51. Out << (Dump ? "Dumping " : "Printing ") << getName(D) << ":\n";
  52. if (ShowColors)
  53. Out.resetColor();
  54. print(D);
  55. Out << "\n";
  56. // Don't traverse child nodes to avoid output duplication.
  57. return true;
  58. }
  59. return base::TraverseDecl(D);
  60. }
  61. private:
  62. std::string getName(Decl *D) {
  63. if (isa<NamedDecl>(D))
  64. return cast<NamedDecl>(D)->getQualifiedNameAsString();
  65. return "";
  66. }
  67. bool filterMatches(Decl *D) {
  68. return getName(D).find(FilterString) != std::string::npos;
  69. }
  70. void print(Decl *D) {
  71. if (DumpLookups) {
  72. if (DeclContext *DC = dyn_cast<DeclContext>(D))
  73. DC->dumpLookups(Out);
  74. else
  75. Out << "Not a DeclContext\n";
  76. } else if (Dump)
  77. D->dump(Out);
  78. else
  79. D->print(Out, /*Indentation=*/0, /*PrintInstantiation=*/true);
  80. }
  81. raw_ostream &Out;
  82. bool Dump;
  83. std::string FilterString;
  84. bool DumpLookups;
  85. };
  86. class ASTDeclNodeLister : public ASTConsumer,
  87. public RecursiveASTVisitor<ASTDeclNodeLister> {
  88. public:
  89. ASTDeclNodeLister(raw_ostream *Out = nullptr)
  90. : Out(Out ? *Out : llvm::outs()) {}
  91. void HandleTranslationUnit(ASTContext &Context) override {
  92. TraverseDecl(Context.getTranslationUnitDecl());
  93. }
  94. bool shouldWalkTypesOfTypeLocs() const { return false; }
  95. bool VisitNamedDecl(NamedDecl *D) {
  96. D->printQualifiedName(Out);
  97. Out << '\n';
  98. return true;
  99. }
  100. private:
  101. raw_ostream &Out;
  102. };
  103. } // end anonymous namespace
  104. ASTConsumer *clang::CreateASTPrinter(raw_ostream *Out,
  105. StringRef FilterString) {
  106. return new ASTPrinter(Out, /*Dump=*/ false, FilterString);
  107. }
  108. ASTConsumer *clang::CreateASTDumper(StringRef FilterString, bool DumpLookups) {
  109. return new ASTPrinter(nullptr, /*Dump=*/true, FilterString, DumpLookups);
  110. }
  111. ASTConsumer *clang::CreateASTDeclNodeLister() {
  112. return new ASTDeclNodeLister(nullptr);
  113. }
  114. //===----------------------------------------------------------------------===//
  115. /// ASTViewer - AST Visualization
  116. namespace {
  117. class ASTViewer : public ASTConsumer {
  118. ASTContext *Context;
  119. public:
  120. void Initialize(ASTContext &Context) override {
  121. this->Context = &Context;
  122. }
  123. bool HandleTopLevelDecl(DeclGroupRef D) override {
  124. for (DeclGroupRef::iterator I = D.begin(), E = D.end(); I != E; ++I)
  125. HandleTopLevelSingleDecl(*I);
  126. return true;
  127. }
  128. void HandleTopLevelSingleDecl(Decl *D);
  129. };
  130. }
  131. void ASTViewer::HandleTopLevelSingleDecl(Decl *D) {
  132. if (isa<FunctionDecl>(D) || isa<ObjCMethodDecl>(D)) {
  133. D->print(llvm::errs());
  134. if (Stmt *Body = D->getBody()) {
  135. llvm::errs() << '\n';
  136. Body->viewAST();
  137. llvm::errs() << '\n';
  138. }
  139. }
  140. }
  141. ASTConsumer *clang::CreateASTViewer() { return new ASTViewer(); }
  142. //===----------------------------------------------------------------------===//
  143. /// DeclContextPrinter - Decl and DeclContext Visualization
  144. namespace {
  145. class DeclContextPrinter : public ASTConsumer {
  146. raw_ostream& Out;
  147. public:
  148. DeclContextPrinter() : Out(llvm::errs()) {}
  149. void HandleTranslationUnit(ASTContext &C) override {
  150. PrintDeclContext(C.getTranslationUnitDecl(), 4);
  151. }
  152. void PrintDeclContext(const DeclContext* DC, unsigned Indentation);
  153. };
  154. } // end anonymous namespace
  155. void DeclContextPrinter::PrintDeclContext(const DeclContext* DC,
  156. unsigned Indentation) {
  157. // Print DeclContext name.
  158. switch (DC->getDeclKind()) {
  159. case Decl::TranslationUnit:
  160. Out << "[translation unit] " << DC;
  161. break;
  162. case Decl::Namespace: {
  163. Out << "[namespace] ";
  164. const NamespaceDecl* ND = cast<NamespaceDecl>(DC);
  165. Out << *ND;
  166. break;
  167. }
  168. case Decl::Enum: {
  169. const EnumDecl* ED = cast<EnumDecl>(DC);
  170. if (ED->isCompleteDefinition())
  171. Out << "[enum] ";
  172. else
  173. Out << "<enum> ";
  174. Out << *ED;
  175. break;
  176. }
  177. case Decl::Record: {
  178. const RecordDecl* RD = cast<RecordDecl>(DC);
  179. if (RD->isCompleteDefinition())
  180. Out << "[struct] ";
  181. else
  182. Out << "<struct> ";
  183. Out << *RD;
  184. break;
  185. }
  186. case Decl::CXXRecord: {
  187. const CXXRecordDecl* RD = cast<CXXRecordDecl>(DC);
  188. if (RD->isCompleteDefinition())
  189. Out << "[class] ";
  190. else
  191. Out << "<class> ";
  192. Out << *RD << ' ' << DC;
  193. break;
  194. }
  195. case Decl::ObjCMethod:
  196. Out << "[objc method]";
  197. break;
  198. case Decl::ObjCInterface:
  199. Out << "[objc interface]";
  200. break;
  201. case Decl::ObjCCategory:
  202. Out << "[objc category]";
  203. break;
  204. case Decl::ObjCProtocol:
  205. Out << "[objc protocol]";
  206. break;
  207. case Decl::ObjCImplementation:
  208. Out << "[objc implementation]";
  209. break;
  210. case Decl::ObjCCategoryImpl:
  211. Out << "[objc categoryimpl]";
  212. break;
  213. case Decl::LinkageSpec:
  214. Out << "[linkage spec]";
  215. break;
  216. case Decl::Block:
  217. Out << "[block]";
  218. break;
  219. case Decl::Function: {
  220. const FunctionDecl* FD = cast<FunctionDecl>(DC);
  221. if (FD->doesThisDeclarationHaveABody())
  222. Out << "[function] ";
  223. else
  224. Out << "<function> ";
  225. Out << *FD;
  226. // Print the parameters.
  227. Out << "(";
  228. bool PrintComma = false;
  229. for (auto I : FD->params()) {
  230. if (PrintComma)
  231. Out << ", ";
  232. else
  233. PrintComma = true;
  234. Out << *I;
  235. }
  236. Out << ")";
  237. break;
  238. }
  239. case Decl::CXXMethod: {
  240. const CXXMethodDecl* D = cast<CXXMethodDecl>(DC);
  241. if (D->isOutOfLine())
  242. Out << "[c++ method] ";
  243. else if (D->isImplicit())
  244. Out << "(c++ method) ";
  245. else
  246. Out << "<c++ method> ";
  247. Out << *D;
  248. // Print the parameters.
  249. Out << "(";
  250. bool PrintComma = false;
  251. for (FunctionDecl::param_const_iterator I = D->param_begin(),
  252. E = D->param_end(); I != E; ++I) {
  253. if (PrintComma)
  254. Out << ", ";
  255. else
  256. PrintComma = true;
  257. Out << **I;
  258. }
  259. Out << ")";
  260. // Check the semantic DeclContext.
  261. const DeclContext* SemaDC = D->getDeclContext();
  262. const DeclContext* LexicalDC = D->getLexicalDeclContext();
  263. if (SemaDC != LexicalDC)
  264. Out << " [[" << SemaDC << "]]";
  265. break;
  266. }
  267. case Decl::CXXConstructor: {
  268. const CXXConstructorDecl* D = cast<CXXConstructorDecl>(DC);
  269. if (D->isOutOfLine())
  270. Out << "[c++ ctor] ";
  271. else if (D->isImplicit())
  272. Out << "(c++ ctor) ";
  273. else
  274. Out << "<c++ ctor> ";
  275. Out << *D;
  276. // Print the parameters.
  277. Out << "(";
  278. bool PrintComma = false;
  279. for (FunctionDecl::param_const_iterator I = D->param_begin(),
  280. E = D->param_end(); I != E; ++I) {
  281. if (PrintComma)
  282. Out << ", ";
  283. else
  284. PrintComma = true;
  285. Out << **I;
  286. }
  287. Out << ")";
  288. // Check the semantic DC.
  289. const DeclContext* SemaDC = D->getDeclContext();
  290. const DeclContext* LexicalDC = D->getLexicalDeclContext();
  291. if (SemaDC != LexicalDC)
  292. Out << " [[" << SemaDC << "]]";
  293. break;
  294. }
  295. case Decl::CXXDestructor: {
  296. const CXXDestructorDecl* D = cast<CXXDestructorDecl>(DC);
  297. if (D->isOutOfLine())
  298. Out << "[c++ dtor] ";
  299. else if (D->isImplicit())
  300. Out << "(c++ dtor) ";
  301. else
  302. Out << "<c++ dtor> ";
  303. Out << *D;
  304. // Check the semantic DC.
  305. const DeclContext* SemaDC = D->getDeclContext();
  306. const DeclContext* LexicalDC = D->getLexicalDeclContext();
  307. if (SemaDC != LexicalDC)
  308. Out << " [[" << SemaDC << "]]";
  309. break;
  310. }
  311. case Decl::CXXConversion: {
  312. const CXXConversionDecl* D = cast<CXXConversionDecl>(DC);
  313. if (D->isOutOfLine())
  314. Out << "[c++ conversion] ";
  315. else if (D->isImplicit())
  316. Out << "(c++ conversion) ";
  317. else
  318. Out << "<c++ conversion> ";
  319. Out << *D;
  320. // Check the semantic DC.
  321. const DeclContext* SemaDC = D->getDeclContext();
  322. const DeclContext* LexicalDC = D->getLexicalDeclContext();
  323. if (SemaDC != LexicalDC)
  324. Out << " [[" << SemaDC << "]]";
  325. break;
  326. }
  327. default:
  328. llvm_unreachable("a decl that inherits DeclContext isn't handled");
  329. }
  330. Out << "\n";
  331. // Print decls in the DeclContext.
  332. for (auto *I : DC->decls()) {
  333. for (unsigned i = 0; i < Indentation; ++i)
  334. Out << " ";
  335. Decl::Kind DK = I->getKind();
  336. switch (DK) {
  337. case Decl::Namespace:
  338. case Decl::Enum:
  339. case Decl::Record:
  340. case Decl::CXXRecord:
  341. case Decl::ObjCMethod:
  342. case Decl::ObjCInterface:
  343. case Decl::ObjCCategory:
  344. case Decl::ObjCProtocol:
  345. case Decl::ObjCImplementation:
  346. case Decl::ObjCCategoryImpl:
  347. case Decl::LinkageSpec:
  348. case Decl::Block:
  349. case Decl::Function:
  350. case Decl::CXXMethod:
  351. case Decl::CXXConstructor:
  352. case Decl::CXXDestructor:
  353. case Decl::CXXConversion:
  354. {
  355. DeclContext* DC = cast<DeclContext>(I);
  356. PrintDeclContext(DC, Indentation+2);
  357. break;
  358. }
  359. case Decl::IndirectField: {
  360. IndirectFieldDecl* IFD = cast<IndirectFieldDecl>(I);
  361. Out << "<IndirectField> " << *IFD << '\n';
  362. break;
  363. }
  364. case Decl::Label: {
  365. LabelDecl *LD = cast<LabelDecl>(I);
  366. Out << "<Label> " << *LD << '\n';
  367. break;
  368. }
  369. case Decl::Field: {
  370. FieldDecl *FD = cast<FieldDecl>(I);
  371. Out << "<field> " << *FD << '\n';
  372. break;
  373. }
  374. case Decl::Typedef:
  375. case Decl::TypeAlias: {
  376. TypedefNameDecl* TD = cast<TypedefNameDecl>(I);
  377. Out << "<typedef> " << *TD << '\n';
  378. break;
  379. }
  380. case Decl::EnumConstant: {
  381. EnumConstantDecl* ECD = cast<EnumConstantDecl>(I);
  382. Out << "<enum constant> " << *ECD << '\n';
  383. break;
  384. }
  385. case Decl::Var: {
  386. VarDecl* VD = cast<VarDecl>(I);
  387. Out << "<var> " << *VD << '\n';
  388. break;
  389. }
  390. case Decl::ImplicitParam: {
  391. ImplicitParamDecl* IPD = cast<ImplicitParamDecl>(I);
  392. Out << "<implicit parameter> " << *IPD << '\n';
  393. break;
  394. }
  395. case Decl::ParmVar: {
  396. ParmVarDecl* PVD = cast<ParmVarDecl>(I);
  397. Out << "<parameter> " << *PVD << '\n';
  398. break;
  399. }
  400. case Decl::ObjCProperty: {
  401. ObjCPropertyDecl* OPD = cast<ObjCPropertyDecl>(I);
  402. Out << "<objc property> " << *OPD << '\n';
  403. break;
  404. }
  405. case Decl::FunctionTemplate: {
  406. FunctionTemplateDecl* FTD = cast<FunctionTemplateDecl>(I);
  407. Out << "<function template> " << *FTD << '\n';
  408. break;
  409. }
  410. case Decl::FileScopeAsm: {
  411. Out << "<file-scope asm>\n";
  412. break;
  413. }
  414. case Decl::UsingDirective: {
  415. Out << "<using directive>\n";
  416. break;
  417. }
  418. case Decl::NamespaceAlias: {
  419. NamespaceAliasDecl* NAD = cast<NamespaceAliasDecl>(I);
  420. Out << "<namespace alias> " << *NAD << '\n';
  421. break;
  422. }
  423. case Decl::ClassTemplate: {
  424. ClassTemplateDecl *CTD = cast<ClassTemplateDecl>(I);
  425. Out << "<class template> " << *CTD << '\n';
  426. break;
  427. }
  428. case Decl::OMPThreadPrivate: {
  429. Out << "<omp threadprivate> " << '"' << I << "\"\n";
  430. break;
  431. }
  432. default:
  433. Out << "DeclKind: " << DK << '"' << I << "\"\n";
  434. llvm_unreachable("decl unhandled");
  435. }
  436. }
  437. }
  438. ASTConsumer *clang::CreateDeclContextPrinter() {
  439. return new DeclContextPrinter();
  440. }