PageRenderTime 51ms CodeModel.GetById 21ms RepoModel.GetById 0ms app.codeStats 1ms

/external/clang/lib/Frontend/ASTConsumers.cpp

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