197e8b6f3c5c578f35c3f392cc7cfdec88cef74f2Chris Lattner//===--- ASTConsumers.cpp - ASTConsumer implementations -------------------===//
25f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer//
35f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer//                     The LLVM Compiler Infrastructure
45f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer//
50bc735ffcfb223c0186419547abaa5c84482663eChris Lattner// This file is distributed under the University of Illinois Open Source
60bc735ffcfb223c0186419547abaa5c84482663eChris Lattner// License. See LICENSE.TXT for details.
75f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer//
85f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer//===----------------------------------------------------------------------===//
95f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer//
1097e8b6f3c5c578f35c3f392cc7cfdec88cef74f2Chris Lattner// AST Consumer Implementations.
115f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer//
125f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer//===----------------------------------------------------------------------===//
135f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer
1439d7c4d2d980651c4263b67cf0ab61dec34cd76bEli Friedman#include "clang/Frontend/ASTConsumers.h"
155f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer#include "clang/AST/AST.h"
163d4997da95b169f0ac32cf83af3368778c429898Chris Lattner#include "clang/AST/ASTConsumer.h"
17557c5b1717bc8919b1b40cf2064b51491ec53a44Chris Lattner#include "clang/AST/ASTContext.h"
18d249e1d1f1498b81314459ceda19d6ff25c278adDouglas Gregor#include "clang/AST/PrettyPrinter.h"
19e34a052d642ba7830174b1a51787251d7f704f80Alexander Kornienko#include "clang/AST/RecordLayout.h"
20e34a052d642ba7830174b1a51787251d7f704f80Alexander Kornienko#include "clang/AST/RecursiveASTVisitor.h"
2155fc873017f10f6f566b182b70f6fc22aefa3464Chandler Carruth#include "clang/Basic/Diagnostic.h"
2255fc873017f10f6f566b182b70f6fc22aefa3464Chandler Carruth#include "clang/Basic/FileManager.h"
2355fc873017f10f6f566b182b70f6fc22aefa3464Chandler Carruth#include "clang/Basic/SourceManager.h"
2403013fa9a0bf1ef4b907f5fec006c8f4000fdd21Michael J. Spencer#include "llvm/Support/Path.h"
25e34a052d642ba7830174b1a51787251d7f704f80Alexander Kornienko#include "llvm/Support/Timer.h"
2655fc873017f10f6f566b182b70f6fc22aefa3464Chandler Carruth#include "llvm/Support/raw_ostream.h"
276000dace22f110d8768476989313e9d981d690d0Chris Lattnerusing namespace clang;
285f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer
291b5a4bdc852cc3d808746bd344a65397067ab1c0Ted Kremenek//===----------------------------------------------------------------------===//
304fe0c8e9c76b96e7aff21696a40dacc09d0237bcDouglas Gregor/// ASTPrinter - Pretty-printer and dumper of ASTs
311b5a4bdc852cc3d808746bd344a65397067ab1c0Ted Kremenek
321b5a4bdc852cc3d808746bd344a65397067ab1c0Ted Kremeneknamespace {
33e34a052d642ba7830174b1a51787251d7f704f80Alexander Kornienko  class ASTPrinter : public ASTConsumer,
34e34a052d642ba7830174b1a51787251d7f704f80Alexander Kornienko                     public RecursiveASTVisitor<ASTPrinter> {
35e34a052d642ba7830174b1a51787251d7f704f80Alexander Kornienko    typedef RecursiveASTVisitor<ASTPrinter> base;
361eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
371b5a4bdc852cc3d808746bd344a65397067ab1c0Ted Kremenek  public:
386bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines    ASTPrinter(raw_ostream *Out = nullptr, bool Dump = false,
39ab297ccbcc51d5197d4ddb4e99b7bc8868d38314Richard Smith               StringRef FilterString = "", bool DumpLookups = false)
40e34a052d642ba7830174b1a51787251d7f704f80Alexander Kornienko        : Out(Out ? *Out : llvm::outs()), Dump(Dump),
41ab297ccbcc51d5197d4ddb4e99b7bc8868d38314Richard Smith          FilterString(FilterString), DumpLookups(DumpLookups) {}
421eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
43651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines    void HandleTranslationUnit(ASTContext &Context) override {
44e34a052d642ba7830174b1a51787251d7f704f80Alexander Kornienko      TranslationUnitDecl *D = Context.getTranslationUnitDecl();
45e34a052d642ba7830174b1a51787251d7f704f80Alexander Kornienko
46ab297ccbcc51d5197d4ddb4e99b7bc8868d38314Richard Smith      if (FilterString.empty())
47ab297ccbcc51d5197d4ddb4e99b7bc8868d38314Richard Smith        return print(D);
48e34a052d642ba7830174b1a51787251d7f704f80Alexander Kornienko
49e34a052d642ba7830174b1a51787251d7f704f80Alexander Kornienko      TraverseDecl(D);
50e34a052d642ba7830174b1a51787251d7f704f80Alexander Kornienko    }
51e34a052d642ba7830174b1a51787251d7f704f80Alexander Kornienko
52e34a052d642ba7830174b1a51787251d7f704f80Alexander Kornienko    bool shouldWalkTypesOfTypeLocs() const { return false; }
53e34a052d642ba7830174b1a51787251d7f704f80Alexander Kornienko
54e34a052d642ba7830174b1a51787251d7f704f80Alexander Kornienko    bool TraverseDecl(Decl *D) {
556bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines      if (D && filterMatches(D)) {
560061fe4094a088863fd47d2509a40cbfcb019f07Dmitri Gribenko        bool ShowColors = Out.has_colors();
570061fe4094a088863fd47d2509a40cbfcb019f07Dmitri Gribenko        if (ShowColors)
58cfa88f893915ceb8ae4ce2f17c46c24a4d67502fDmitri Gribenko          Out.changeColor(raw_ostream::BLUE);
59176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines        Out << ((Dump || DumpLookups) ? "Dumping " : "Printing ") << getName(D)
60176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines            << ":\n";
610061fe4094a088863fd47d2509a40cbfcb019f07Dmitri Gribenko        if (ShowColors)
620061fe4094a088863fd47d2509a40cbfcb019f07Dmitri Gribenko          Out.resetColor();
63ab297ccbcc51d5197d4ddb4e99b7bc8868d38314Richard Smith        print(D);
64a7612aec79bf7f7c7791941aa0a5c59b1dc82463Alexander Kornienko        Out << "\n";
65e34a052d642ba7830174b1a51787251d7f704f80Alexander Kornienko        // Don't traverse child nodes to avoid output duplication.
66e34a052d642ba7830174b1a51787251d7f704f80Alexander Kornienko        return true;
67e34a052d642ba7830174b1a51787251d7f704f80Alexander Kornienko      }
68e34a052d642ba7830174b1a51787251d7f704f80Alexander Kornienko      return base::TraverseDecl(D);
69e34a052d642ba7830174b1a51787251d7f704f80Alexander Kornienko    }
70e34a052d642ba7830174b1a51787251d7f704f80Alexander Kornienko
71e34a052d642ba7830174b1a51787251d7f704f80Alexander Kornienko  private:
72e34a052d642ba7830174b1a51787251d7f704f80Alexander Kornienko    std::string getName(Decl *D) {
73e34a052d642ba7830174b1a51787251d7f704f80Alexander Kornienko      if (isa<NamedDecl>(D))
74e34a052d642ba7830174b1a51787251d7f704f80Alexander Kornienko        return cast<NamedDecl>(D)->getQualifiedNameAsString();
75e34a052d642ba7830174b1a51787251d7f704f80Alexander Kornienko      return "";
76e34a052d642ba7830174b1a51787251d7f704f80Alexander Kornienko    }
77e34a052d642ba7830174b1a51787251d7f704f80Alexander Kornienko    bool filterMatches(Decl *D) {
78e34a052d642ba7830174b1a51787251d7f704f80Alexander Kornienko      return getName(D).find(FilterString) != std::string::npos;
795f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer    }
80ab297ccbcc51d5197d4ddb4e99b7bc8868d38314Richard Smith    void print(Decl *D) {
81ab297ccbcc51d5197d4ddb4e99b7bc8868d38314Richard Smith      if (DumpLookups) {
82176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines        if (DeclContext *DC = dyn_cast<DeclContext>(D)) {
83176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines          if (DC == DC->getPrimaryContext())
84176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines            DC->dumpLookups(Out, Dump);
85176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines          else
86176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines            Out << "Lookup map is in primary DeclContext "
87176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines                << DC->getPrimaryContext() << "\n";
88176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines        } else
89ab297ccbcc51d5197d4ddb4e99b7bc8868d38314Richard Smith          Out << "Not a DeclContext\n";
90ab297ccbcc51d5197d4ddb4e99b7bc8868d38314Richard Smith      } else if (Dump)
91ab297ccbcc51d5197d4ddb4e99b7bc8868d38314Richard Smith        D->dump(Out);
92ab297ccbcc51d5197d4ddb4e99b7bc8868d38314Richard Smith      else
93ab297ccbcc51d5197d4ddb4e99b7bc8868d38314Richard Smith        D->print(Out, /*Indentation=*/0, /*PrintInstantiation=*/true);
94ab297ccbcc51d5197d4ddb4e99b7bc8868d38314Richard Smith    }
95e34a052d642ba7830174b1a51787251d7f704f80Alexander Kornienko
96e34a052d642ba7830174b1a51787251d7f704f80Alexander Kornienko    raw_ostream &Out;
97e34a052d642ba7830174b1a51787251d7f704f80Alexander Kornienko    bool Dump;
98e34a052d642ba7830174b1a51787251d7f704f80Alexander Kornienko    std::string FilterString;
99ab297ccbcc51d5197d4ddb4e99b7bc8868d38314Richard Smith    bool DumpLookups;
1003d4997da95b169f0ac32cf83af3368778c429898Chris Lattner  };
101171af64ef10ae816ed2a4f15f5d17aca1d71769fAlexander Kornienko
102171af64ef10ae816ed2a4f15f5d17aca1d71769fAlexander Kornienko  class ASTDeclNodeLister : public ASTConsumer,
103171af64ef10ae816ed2a4f15f5d17aca1d71769fAlexander Kornienko                     public RecursiveASTVisitor<ASTDeclNodeLister> {
104171af64ef10ae816ed2a4f15f5d17aca1d71769fAlexander Kornienko  public:
1056bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines    ASTDeclNodeLister(raw_ostream *Out = nullptr)
106171af64ef10ae816ed2a4f15f5d17aca1d71769fAlexander Kornienko        : Out(Out ? *Out : llvm::outs()) {}
107171af64ef10ae816ed2a4f15f5d17aca1d71769fAlexander Kornienko
108651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines    void HandleTranslationUnit(ASTContext &Context) override {
109171af64ef10ae816ed2a4f15f5d17aca1d71769fAlexander Kornienko      TraverseDecl(Context.getTranslationUnitDecl());
110171af64ef10ae816ed2a4f15f5d17aca1d71769fAlexander Kornienko    }
111171af64ef10ae816ed2a4f15f5d17aca1d71769fAlexander Kornienko
112171af64ef10ae816ed2a4f15f5d17aca1d71769fAlexander Kornienko    bool shouldWalkTypesOfTypeLocs() const { return false; }
113171af64ef10ae816ed2a4f15f5d17aca1d71769fAlexander Kornienko
114651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines    bool VisitNamedDecl(NamedDecl *D) {
115b063ef0222a99ee168631afa7b5a882d494b8fdeBenjamin Kramer      D->printQualifiedName(Out);
116b063ef0222a99ee168631afa7b5a882d494b8fdeBenjamin Kramer      Out << '\n';
117171af64ef10ae816ed2a4f15f5d17aca1d71769fAlexander Kornienko      return true;
118171af64ef10ae816ed2a4f15f5d17aca1d71769fAlexander Kornienko    }
119171af64ef10ae816ed2a4f15f5d17aca1d71769fAlexander Kornienko
120171af64ef10ae816ed2a4f15f5d17aca1d71769fAlexander Kornienko  private:
121171af64ef10ae816ed2a4f15f5d17aca1d71769fAlexander Kornienko    raw_ostream &Out;
122171af64ef10ae816ed2a4f15f5d17aca1d71769fAlexander Kornienko  };
123b23ff6b4ebefe9c0fd531d2247171500e5d0a5b7Chris Lattner} // end anonymous namespace
1246000dace22f110d8768476989313e9d981d690d0Chris Lattner
125176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hinesstd::unique_ptr<ASTConsumer> clang::CreateASTPrinter(raw_ostream *Out,
126176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines                                                     StringRef FilterString) {
127176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines  return llvm::make_unique<ASTPrinter>(Out, /*Dump=*/false, FilterString);
128ea75c5599072bda2dc9fc1dec2e680936c84f6f1Ted Kremenek}
1291b5a4bdc852cc3d808746bd344a65397067ab1c0Ted Kremenek
130176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hinesstd::unique_ptr<ASTConsumer> clang::CreateASTDumper(StringRef FilterString,
131176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines                                                    bool DumpDecls,
132176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines                                                    bool DumpLookups) {
133176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines  assert((DumpDecls || DumpLookups) && "nothing to dump");
134176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines  return llvm::make_unique<ASTPrinter>(nullptr, DumpDecls, FilterString,
135176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines                                       DumpLookups);
136609e72f55a04cbef59a7d493d5121c066ca3dff5Douglas Gregor}
1373d4997da95b169f0ac32cf83af3368778c429898Chris Lattner
138176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hinesstd::unique_ptr<ASTConsumer> clang::CreateASTDeclNodeLister() {
139176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines  return llvm::make_unique<ASTDeclNodeLister>(nullptr);
140171af64ef10ae816ed2a4f15f5d17aca1d71769fAlexander Kornienko}
141171af64ef10ae816ed2a4f15f5d17aca1d71769fAlexander Kornienko
1421b5a4bdc852cc3d808746bd344a65397067ab1c0Ted Kremenek//===----------------------------------------------------------------------===//
1431b5a4bdc852cc3d808746bd344a65397067ab1c0Ted Kremenek/// ASTViewer - AST Visualization
1441b5a4bdc852cc3d808746bd344a65397067ab1c0Ted Kremenek
14580de08fc6f7ebfee07b1b2c520c99e31c3243365Ted Kremeneknamespace {
14680de08fc6f7ebfee07b1b2c520c99e31c3243365Ted Kremenek  class ASTViewer : public ASTConsumer {
1474fe0c8e9c76b96e7aff21696a40dacc09d0237bcDouglas Gregor    ASTContext *Context;
14880de08fc6f7ebfee07b1b2c520c99e31c3243365Ted Kremenek  public:
149651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines    void Initialize(ASTContext &Context) override {
1504fe0c8e9c76b96e7aff21696a40dacc09d0237bcDouglas Gregor      this->Context = &Context;
15180de08fc6f7ebfee07b1b2c520c99e31c3243365Ted Kremenek    }
152682bf92db408a6cbc3d37b5496a99b6ef85041ecChris Lattner
153651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines    bool HandleTopLevelDecl(DeclGroupRef D) override {
154682bf92db408a6cbc3d37b5496a99b6ef85041ecChris Lattner      for (DeclGroupRef::iterator I = D.begin(), E = D.end(); I != E; ++I)
155682bf92db408a6cbc3d37b5496a99b6ef85041ecChris Lattner        HandleTopLevelSingleDecl(*I);
15688c2596edc8eb475e20f6033de1ea01669695a0cArgyrios Kyrtzidis      return true;
157682bf92db408a6cbc3d37b5496a99b6ef85041ecChris Lattner    }
1581eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
159682bf92db408a6cbc3d37b5496a99b6ef85041ecChris Lattner    void HandleTopLevelSingleDecl(Decl *D);
16080de08fc6f7ebfee07b1b2c520c99e31c3243365Ted Kremenek  };
16180de08fc6f7ebfee07b1b2c520c99e31c3243365Ted Kremenek}
16280de08fc6f7ebfee07b1b2c520c99e31c3243365Ted Kremenek
163682bf92db408a6cbc3d37b5496a99b6ef85041ecChris Lattnervoid ASTViewer::HandleTopLevelSingleDecl(Decl *D) {
1649d96f9239e9250864435b25ed93bf6d08c4e5febArgyrios Kyrtzidis  if (isa<FunctionDecl>(D) || isa<ObjCMethodDecl>(D)) {
1659d96f9239e9250864435b25ed93bf6d08c4e5febArgyrios Kyrtzidis    D->print(llvm::errs());
1669d96f9239e9250864435b25ed93bf6d08c4e5febArgyrios Kyrtzidis
1679d96f9239e9250864435b25ed93bf6d08c4e5febArgyrios Kyrtzidis    if (Stmt *Body = D->getBody()) {
1686cb7c1a43b0c8f739d1f54b7fdae5ede86033496Benjamin Kramer      llvm::errs() << '\n';
169af3280fadbdab6305581955c973e1229970958ebDouglas Gregor      Body->viewAST();
1706cb7c1a43b0c8f739d1f54b7fdae5ede86033496Benjamin Kramer      llvm::errs() << '\n';
171b23ff6b4ebefe9c0fd531d2247171500e5d0a5b7Chris Lattner    }
172b23ff6b4ebefe9c0fd531d2247171500e5d0a5b7Chris Lattner  }
173b23ff6b4ebefe9c0fd531d2247171500e5d0a5b7Chris Lattner}
174b23ff6b4ebefe9c0fd531d2247171500e5d0a5b7Chris Lattner
175176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hinesstd::unique_ptr<ASTConsumer> clang::CreateASTViewer() {
176176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines  return llvm::make_unique<ASTViewer>();
177176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines}
17880de08fc6f7ebfee07b1b2c520c99e31c3243365Ted Kremenek
17974bf2c9a4c749e9facba90b3a3ab3f369efa7682Ted Kremenek//===----------------------------------------------------------------------===//
1802d75d6f56c2937d67aecb6008793694f9eb51349Zhongxing Xu/// DeclContextPrinter - Decl and DeclContext Visualization
1812d75d6f56c2937d67aecb6008793694f9eb51349Zhongxing Xu
1822d75d6f56c2937d67aecb6008793694f9eb51349Zhongxing Xunamespace {
1832d75d6f56c2937d67aecb6008793694f9eb51349Zhongxing Xu
1842d75d6f56c2937d67aecb6008793694f9eb51349Zhongxing Xuclass DeclContextPrinter : public ASTConsumer {
1855f9e272e632e951b1efe824cd16acb4d96077930Chris Lattner  raw_ostream& Out;
1862d75d6f56c2937d67aecb6008793694f9eb51349Zhongxing Xupublic:
1872d75d6f56c2937d67aecb6008793694f9eb51349Zhongxing Xu  DeclContextPrinter() : Out(llvm::errs()) {}
1882d75d6f56c2937d67aecb6008793694f9eb51349Zhongxing Xu
189651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  void HandleTranslationUnit(ASTContext &C) override {
190dacbc5d46aaeea817742b8c76c987b87d2490c85Chris Lattner    PrintDeclContext(C.getTranslationUnitDecl(), 4);
1912d75d6f56c2937d67aecb6008793694f9eb51349Zhongxing Xu  }
1922d75d6f56c2937d67aecb6008793694f9eb51349Zhongxing Xu
1932d75d6f56c2937d67aecb6008793694f9eb51349Zhongxing Xu  void PrintDeclContext(const DeclContext* DC, unsigned Indentation);
1942d75d6f56c2937d67aecb6008793694f9eb51349Zhongxing Xu};
195b23ff6b4ebefe9c0fd531d2247171500e5d0a5b7Chris Lattner}  // end anonymous namespace
1962d75d6f56c2937d67aecb6008793694f9eb51349Zhongxing Xu
1971eb4433ac451dc16f4133a88af2d002ac26c58efMike Stumpvoid DeclContextPrinter::PrintDeclContext(const DeclContext* DC,
1982d75d6f56c2937d67aecb6008793694f9eb51349Zhongxing Xu                                          unsigned Indentation) {
1992d75d6f56c2937d67aecb6008793694f9eb51349Zhongxing Xu  // Print DeclContext name.
2009b9ca01ff3136a7539dc08a4c4e1a3dd8c8d3a7dArgyrios Kyrtzidis  switch (DC->getDeclKind()) {
2012d75d6f56c2937d67aecb6008793694f9eb51349Zhongxing Xu  case Decl::TranslationUnit:
2022d75d6f56c2937d67aecb6008793694f9eb51349Zhongxing Xu    Out << "[translation unit] " << DC;
2032d75d6f56c2937d67aecb6008793694f9eb51349Zhongxing Xu    break;
2042d75d6f56c2937d67aecb6008793694f9eb51349Zhongxing Xu  case Decl::Namespace: {
2052d75d6f56c2937d67aecb6008793694f9eb51349Zhongxing Xu    Out << "[namespace] ";
2067ad5bf3152d4fe8f0de4611347fc6e24c45fba60Argyrios Kyrtzidis    const NamespaceDecl* ND = cast<NamespaceDecl>(DC);
207b8989f27f116ff2400e92a52c067a69846119eb5Benjamin Kramer    Out << *ND;
2082d75d6f56c2937d67aecb6008793694f9eb51349Zhongxing Xu    break;
2092d75d6f56c2937d67aecb6008793694f9eb51349Zhongxing Xu  }
210867c39e8c4a2ccdbc1edae45966dc5f3e910954bZhongxing Xu  case Decl::Enum: {
2117ad5bf3152d4fe8f0de4611347fc6e24c45fba60Argyrios Kyrtzidis    const EnumDecl* ED = cast<EnumDecl>(DC);
2125e1cdac63c3d9c9b32fa41fa0b2d242a58a20d49John McCall    if (ED->isCompleteDefinition())
213867c39e8c4a2ccdbc1edae45966dc5f3e910954bZhongxing Xu      Out << "[enum] ";
214867c39e8c4a2ccdbc1edae45966dc5f3e910954bZhongxing Xu    else
215867c39e8c4a2ccdbc1edae45966dc5f3e910954bZhongxing Xu      Out << "<enum> ";
216b8989f27f116ff2400e92a52c067a69846119eb5Benjamin Kramer    Out << *ED;
2172d75d6f56c2937d67aecb6008793694f9eb51349Zhongxing Xu    break;
218867c39e8c4a2ccdbc1edae45966dc5f3e910954bZhongxing Xu  }
2192d75d6f56c2937d67aecb6008793694f9eb51349Zhongxing Xu  case Decl::Record: {
2207ad5bf3152d4fe8f0de4611347fc6e24c45fba60Argyrios Kyrtzidis    const RecordDecl* RD = cast<RecordDecl>(DC);
2215e1cdac63c3d9c9b32fa41fa0b2d242a58a20d49John McCall    if (RD->isCompleteDefinition())
2222d75d6f56c2937d67aecb6008793694f9eb51349Zhongxing Xu      Out << "[struct] ";
2232d75d6f56c2937d67aecb6008793694f9eb51349Zhongxing Xu    else
2242d75d6f56c2937d67aecb6008793694f9eb51349Zhongxing Xu      Out << "<struct> ";
225b8989f27f116ff2400e92a52c067a69846119eb5Benjamin Kramer    Out << *RD;
2262d75d6f56c2937d67aecb6008793694f9eb51349Zhongxing Xu    break;
2272d75d6f56c2937d67aecb6008793694f9eb51349Zhongxing Xu  }
2282d75d6f56c2937d67aecb6008793694f9eb51349Zhongxing Xu  case Decl::CXXRecord: {
2297ad5bf3152d4fe8f0de4611347fc6e24c45fba60Argyrios Kyrtzidis    const CXXRecordDecl* RD = cast<CXXRecordDecl>(DC);
2305e1cdac63c3d9c9b32fa41fa0b2d242a58a20d49John McCall    if (RD->isCompleteDefinition())
2312d75d6f56c2937d67aecb6008793694f9eb51349Zhongxing Xu      Out << "[class] ";
2322d75d6f56c2937d67aecb6008793694f9eb51349Zhongxing Xu    else
2332d75d6f56c2937d67aecb6008793694f9eb51349Zhongxing Xu      Out << "<class> ";
234b8989f27f116ff2400e92a52c067a69846119eb5Benjamin Kramer    Out << *RD << ' ' << DC;
2352d75d6f56c2937d67aecb6008793694f9eb51349Zhongxing Xu    break;
2362d75d6f56c2937d67aecb6008793694f9eb51349Zhongxing Xu  }
2372d75d6f56c2937d67aecb6008793694f9eb51349Zhongxing Xu  case Decl::ObjCMethod:
2382d75d6f56c2937d67aecb6008793694f9eb51349Zhongxing Xu    Out << "[objc method]";
2392d75d6f56c2937d67aecb6008793694f9eb51349Zhongxing Xu    break;
2402d75d6f56c2937d67aecb6008793694f9eb51349Zhongxing Xu  case Decl::ObjCInterface:
2412d75d6f56c2937d67aecb6008793694f9eb51349Zhongxing Xu    Out << "[objc interface]";
2422d75d6f56c2937d67aecb6008793694f9eb51349Zhongxing Xu    break;
2432d75d6f56c2937d67aecb6008793694f9eb51349Zhongxing Xu  case Decl::ObjCCategory:
2442d75d6f56c2937d67aecb6008793694f9eb51349Zhongxing Xu    Out << "[objc category]";
2452d75d6f56c2937d67aecb6008793694f9eb51349Zhongxing Xu    break;
2462d75d6f56c2937d67aecb6008793694f9eb51349Zhongxing Xu  case Decl::ObjCProtocol:
2472d75d6f56c2937d67aecb6008793694f9eb51349Zhongxing Xu    Out << "[objc protocol]";
2482d75d6f56c2937d67aecb6008793694f9eb51349Zhongxing Xu    break;
2492d75d6f56c2937d67aecb6008793694f9eb51349Zhongxing Xu  case Decl::ObjCImplementation:
2502d75d6f56c2937d67aecb6008793694f9eb51349Zhongxing Xu    Out << "[objc implementation]";
2512d75d6f56c2937d67aecb6008793694f9eb51349Zhongxing Xu    break;
2522d75d6f56c2937d67aecb6008793694f9eb51349Zhongxing Xu  case Decl::ObjCCategoryImpl:
2532d75d6f56c2937d67aecb6008793694f9eb51349Zhongxing Xu    Out << "[objc categoryimpl]";
2542d75d6f56c2937d67aecb6008793694f9eb51349Zhongxing Xu    break;
2552d75d6f56c2937d67aecb6008793694f9eb51349Zhongxing Xu  case Decl::LinkageSpec:
2562d75d6f56c2937d67aecb6008793694f9eb51349Zhongxing Xu    Out << "[linkage spec]";
2572d75d6f56c2937d67aecb6008793694f9eb51349Zhongxing Xu    break;
2582d75d6f56c2937d67aecb6008793694f9eb51349Zhongxing Xu  case Decl::Block:
2592d75d6f56c2937d67aecb6008793694f9eb51349Zhongxing Xu    Out << "[block]";
2602d75d6f56c2937d67aecb6008793694f9eb51349Zhongxing Xu    break;
2612d75d6f56c2937d67aecb6008793694f9eb51349Zhongxing Xu  case Decl::Function: {
2627ad5bf3152d4fe8f0de4611347fc6e24c45fba60Argyrios Kyrtzidis    const FunctionDecl* FD = cast<FunctionDecl>(DC);
26310620eb5164e31208fcbf0437cd79ae535ed0559Sean Hunt    if (FD->doesThisDeclarationHaveABody())
2642d75d6f56c2937d67aecb6008793694f9eb51349Zhongxing Xu      Out << "[function] ";
2652d75d6f56c2937d67aecb6008793694f9eb51349Zhongxing Xu    else
2662d75d6f56c2937d67aecb6008793694f9eb51349Zhongxing Xu      Out << "<function> ";
267b8989f27f116ff2400e92a52c067a69846119eb5Benjamin Kramer    Out << *FD;
268ca04ce46e1458089a1dec90d19d7d676a8229bd1Zhongxing Xu    // Print the parameters.
269ca04ce46e1458089a1dec90d19d7d676a8229bd1Zhongxing Xu    Out << "(";
270ca04ce46e1458089a1dec90d19d7d676a8229bd1Zhongxing Xu    bool PrintComma = false;
2714967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar    for (auto I : FD->parameters()) {
272ca04ce46e1458089a1dec90d19d7d676a8229bd1Zhongxing Xu      if (PrintComma)
273ca04ce46e1458089a1dec90d19d7d676a8229bd1Zhongxing Xu        Out << ", ";
274ca04ce46e1458089a1dec90d19d7d676a8229bd1Zhongxing Xu      else
275ca04ce46e1458089a1dec90d19d7d676a8229bd1Zhongxing Xu        PrintComma = true;
276651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines      Out << *I;
277ca04ce46e1458089a1dec90d19d7d676a8229bd1Zhongxing Xu    }
278ca04ce46e1458089a1dec90d19d7d676a8229bd1Zhongxing Xu    Out << ")";
2792d75d6f56c2937d67aecb6008793694f9eb51349Zhongxing Xu    break;
2802d75d6f56c2937d67aecb6008793694f9eb51349Zhongxing Xu  }
2812d75d6f56c2937d67aecb6008793694f9eb51349Zhongxing Xu  case Decl::CXXMethod: {
2827ad5bf3152d4fe8f0de4611347fc6e24c45fba60Argyrios Kyrtzidis    const CXXMethodDecl* D = cast<CXXMethodDecl>(DC);
283f5cecfbdcd20be224861f9e67c5973a9a2b61512Argyrios Kyrtzidis    if (D->isOutOfLine())
2842d75d6f56c2937d67aecb6008793694f9eb51349Zhongxing Xu      Out << "[c++ method] ";
2852a3eb0e22e671112ab19b62e9a40615d195a7f17Zhongxing Xu    else if (D->isImplicit())
2862a3eb0e22e671112ab19b62e9a40615d195a7f17Zhongxing Xu      Out << "(c++ method) ";
2872d75d6f56c2937d67aecb6008793694f9eb51349Zhongxing Xu    else
2882d75d6f56c2937d67aecb6008793694f9eb51349Zhongxing Xu      Out << "<c++ method> ";
289b8989f27f116ff2400e92a52c067a69846119eb5Benjamin Kramer    Out << *D;
290ca04ce46e1458089a1dec90d19d7d676a8229bd1Zhongxing Xu    // Print the parameters.
291ca04ce46e1458089a1dec90d19d7d676a8229bd1Zhongxing Xu    Out << "(";
292ca04ce46e1458089a1dec90d19d7d676a8229bd1Zhongxing Xu    bool PrintComma = false;
2934967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar    for (ParmVarDecl *Parameter : D->parameters()) {
294ca04ce46e1458089a1dec90d19d7d676a8229bd1Zhongxing Xu      if (PrintComma)
295ca04ce46e1458089a1dec90d19d7d676a8229bd1Zhongxing Xu        Out << ", ";
296ca04ce46e1458089a1dec90d19d7d676a8229bd1Zhongxing Xu      else
297ca04ce46e1458089a1dec90d19d7d676a8229bd1Zhongxing Xu        PrintComma = true;
2984967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar      Out << *Parameter;
299ca04ce46e1458089a1dec90d19d7d676a8229bd1Zhongxing Xu    }
300ca04ce46e1458089a1dec90d19d7d676a8229bd1Zhongxing Xu    Out << ")";
3012d75d6f56c2937d67aecb6008793694f9eb51349Zhongxing Xu
3022d75d6f56c2937d67aecb6008793694f9eb51349Zhongxing Xu    // Check the semantic DeclContext.
3037ad5bf3152d4fe8f0de4611347fc6e24c45fba60Argyrios Kyrtzidis    const DeclContext* SemaDC = D->getDeclContext();
3047ad5bf3152d4fe8f0de4611347fc6e24c45fba60Argyrios Kyrtzidis    const DeclContext* LexicalDC = D->getLexicalDeclContext();
3052a3eb0e22e671112ab19b62e9a40615d195a7f17Zhongxing Xu    if (SemaDC != LexicalDC)
3062d75d6f56c2937d67aecb6008793694f9eb51349Zhongxing Xu      Out << " [[" << SemaDC << "]]";
3072a3eb0e22e671112ab19b62e9a40615d195a7f17Zhongxing Xu
3082d75d6f56c2937d67aecb6008793694f9eb51349Zhongxing Xu    break;
3092d75d6f56c2937d67aecb6008793694f9eb51349Zhongxing Xu  }
3102d75d6f56c2937d67aecb6008793694f9eb51349Zhongxing Xu  case Decl::CXXConstructor: {
3117ad5bf3152d4fe8f0de4611347fc6e24c45fba60Argyrios Kyrtzidis    const CXXConstructorDecl* D = cast<CXXConstructorDecl>(DC);
312f5cecfbdcd20be224861f9e67c5973a9a2b61512Argyrios Kyrtzidis    if (D->isOutOfLine())
3132d75d6f56c2937d67aecb6008793694f9eb51349Zhongxing Xu      Out << "[c++ ctor] ";
3142a3eb0e22e671112ab19b62e9a40615d195a7f17Zhongxing Xu    else if (D->isImplicit())
3152a3eb0e22e671112ab19b62e9a40615d195a7f17Zhongxing Xu      Out << "(c++ ctor) ";
3162d75d6f56c2937d67aecb6008793694f9eb51349Zhongxing Xu    else
3172d75d6f56c2937d67aecb6008793694f9eb51349Zhongxing Xu      Out << "<c++ ctor> ";
318b8989f27f116ff2400e92a52c067a69846119eb5Benjamin Kramer    Out << *D;
319ca04ce46e1458089a1dec90d19d7d676a8229bd1Zhongxing Xu    // Print the parameters.
320ca04ce46e1458089a1dec90d19d7d676a8229bd1Zhongxing Xu    Out << "(";
321ca04ce46e1458089a1dec90d19d7d676a8229bd1Zhongxing Xu    bool PrintComma = false;
3224967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar    for (ParmVarDecl *Parameter : D->parameters()) {
323ca04ce46e1458089a1dec90d19d7d676a8229bd1Zhongxing Xu      if (PrintComma)
324ca04ce46e1458089a1dec90d19d7d676a8229bd1Zhongxing Xu        Out << ", ";
325ca04ce46e1458089a1dec90d19d7d676a8229bd1Zhongxing Xu      else
326ca04ce46e1458089a1dec90d19d7d676a8229bd1Zhongxing Xu        PrintComma = true;
3274967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar      Out << *Parameter;
328ca04ce46e1458089a1dec90d19d7d676a8229bd1Zhongxing Xu    }
329ca04ce46e1458089a1dec90d19d7d676a8229bd1Zhongxing Xu    Out << ")";
330ca04ce46e1458089a1dec90d19d7d676a8229bd1Zhongxing Xu
3312a3eb0e22e671112ab19b62e9a40615d195a7f17Zhongxing Xu    // Check the semantic DC.
3327ad5bf3152d4fe8f0de4611347fc6e24c45fba60Argyrios Kyrtzidis    const DeclContext* SemaDC = D->getDeclContext();
3337ad5bf3152d4fe8f0de4611347fc6e24c45fba60Argyrios Kyrtzidis    const DeclContext* LexicalDC = D->getLexicalDeclContext();
3342a3eb0e22e671112ab19b62e9a40615d195a7f17Zhongxing Xu    if (SemaDC != LexicalDC)
3352a3eb0e22e671112ab19b62e9a40615d195a7f17Zhongxing Xu      Out << " [[" << SemaDC << "]]";
3362d75d6f56c2937d67aecb6008793694f9eb51349Zhongxing Xu    break;
3372d75d6f56c2937d67aecb6008793694f9eb51349Zhongxing Xu  }
3382d75d6f56c2937d67aecb6008793694f9eb51349Zhongxing Xu  case Decl::CXXDestructor: {
3397ad5bf3152d4fe8f0de4611347fc6e24c45fba60Argyrios Kyrtzidis    const CXXDestructorDecl* D = cast<CXXDestructorDecl>(DC);
340f5cecfbdcd20be224861f9e67c5973a9a2b61512Argyrios Kyrtzidis    if (D->isOutOfLine())
3412d75d6f56c2937d67aecb6008793694f9eb51349Zhongxing Xu      Out << "[c++ dtor] ";
3422a3eb0e22e671112ab19b62e9a40615d195a7f17Zhongxing Xu    else if (D->isImplicit())
3432a3eb0e22e671112ab19b62e9a40615d195a7f17Zhongxing Xu      Out << "(c++ dtor) ";
3442d75d6f56c2937d67aecb6008793694f9eb51349Zhongxing Xu    else
3452d75d6f56c2937d67aecb6008793694f9eb51349Zhongxing Xu      Out << "<c++ dtor> ";
346b8989f27f116ff2400e92a52c067a69846119eb5Benjamin Kramer    Out << *D;
3472a3eb0e22e671112ab19b62e9a40615d195a7f17Zhongxing Xu    // Check the semantic DC.
3487ad5bf3152d4fe8f0de4611347fc6e24c45fba60Argyrios Kyrtzidis    const DeclContext* SemaDC = D->getDeclContext();
3497ad5bf3152d4fe8f0de4611347fc6e24c45fba60Argyrios Kyrtzidis    const DeclContext* LexicalDC = D->getLexicalDeclContext();
3502a3eb0e22e671112ab19b62e9a40615d195a7f17Zhongxing Xu    if (SemaDC != LexicalDC)
3512a3eb0e22e671112ab19b62e9a40615d195a7f17Zhongxing Xu      Out << " [[" << SemaDC << "]]";
3522d75d6f56c2937d67aecb6008793694f9eb51349Zhongxing Xu    break;
3532d75d6f56c2937d67aecb6008793694f9eb51349Zhongxing Xu  }
3542d75d6f56c2937d67aecb6008793694f9eb51349Zhongxing Xu  case Decl::CXXConversion: {
3557ad5bf3152d4fe8f0de4611347fc6e24c45fba60Argyrios Kyrtzidis    const CXXConversionDecl* D = cast<CXXConversionDecl>(DC);
356f5cecfbdcd20be224861f9e67c5973a9a2b61512Argyrios Kyrtzidis    if (D->isOutOfLine())
3572d75d6f56c2937d67aecb6008793694f9eb51349Zhongxing Xu      Out << "[c++ conversion] ";
3582a3eb0e22e671112ab19b62e9a40615d195a7f17Zhongxing Xu    else if (D->isImplicit())
3592a3eb0e22e671112ab19b62e9a40615d195a7f17Zhongxing Xu      Out << "(c++ conversion) ";
3602d75d6f56c2937d67aecb6008793694f9eb51349Zhongxing Xu    else
3612d75d6f56c2937d67aecb6008793694f9eb51349Zhongxing Xu      Out << "<c++ conversion> ";
362b8989f27f116ff2400e92a52c067a69846119eb5Benjamin Kramer    Out << *D;
3632a3eb0e22e671112ab19b62e9a40615d195a7f17Zhongxing Xu    // Check the semantic DC.
3647ad5bf3152d4fe8f0de4611347fc6e24c45fba60Argyrios Kyrtzidis    const DeclContext* SemaDC = D->getDeclContext();
3657ad5bf3152d4fe8f0de4611347fc6e24c45fba60Argyrios Kyrtzidis    const DeclContext* LexicalDC = D->getLexicalDeclContext();
3662a3eb0e22e671112ab19b62e9a40615d195a7f17Zhongxing Xu    if (SemaDC != LexicalDC)
3672a3eb0e22e671112ab19b62e9a40615d195a7f17Zhongxing Xu      Out << " [[" << SemaDC << "]]";
3682d75d6f56c2937d67aecb6008793694f9eb51349Zhongxing Xu    break;
3692d75d6f56c2937d67aecb6008793694f9eb51349Zhongxing Xu  }
3702d75d6f56c2937d67aecb6008793694f9eb51349Zhongxing Xu
3712d75d6f56c2937d67aecb6008793694f9eb51349Zhongxing Xu  default:
372b219cfc4d75f0a03630b7c4509ef791b7e97b2c8David Blaikie    llvm_unreachable("a decl that inherits DeclContext isn't handled");
3732d75d6f56c2937d67aecb6008793694f9eb51349Zhongxing Xu  }
3742d75d6f56c2937d67aecb6008793694f9eb51349Zhongxing Xu
3752d75d6f56c2937d67aecb6008793694f9eb51349Zhongxing Xu  Out << "\n";
3762d75d6f56c2937d67aecb6008793694f9eb51349Zhongxing Xu
3772d75d6f56c2937d67aecb6008793694f9eb51349Zhongxing Xu  // Print decls in the DeclContext.
378651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  for (auto *I : DC->decls()) {
3792d75d6f56c2937d67aecb6008793694f9eb51349Zhongxing Xu    for (unsigned i = 0; i < Indentation; ++i)
380071e4da10b07ca5278a7ce9dcabd853e0d57e5a4Mike Stump      Out << "  ";
3812d75d6f56c2937d67aecb6008793694f9eb51349Zhongxing Xu
3822d75d6f56c2937d67aecb6008793694f9eb51349Zhongxing Xu    Decl::Kind DK = I->getKind();
3832d75d6f56c2937d67aecb6008793694f9eb51349Zhongxing Xu    switch (DK) {
3842d75d6f56c2937d67aecb6008793694f9eb51349Zhongxing Xu    case Decl::Namespace:
3852d75d6f56c2937d67aecb6008793694f9eb51349Zhongxing Xu    case Decl::Enum:
3862d75d6f56c2937d67aecb6008793694f9eb51349Zhongxing Xu    case Decl::Record:
3872d75d6f56c2937d67aecb6008793694f9eb51349Zhongxing Xu    case Decl::CXXRecord:
3882d75d6f56c2937d67aecb6008793694f9eb51349Zhongxing Xu    case Decl::ObjCMethod:
3892d75d6f56c2937d67aecb6008793694f9eb51349Zhongxing Xu    case Decl::ObjCInterface:
3901eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump    case Decl::ObjCCategory:
3912d75d6f56c2937d67aecb6008793694f9eb51349Zhongxing Xu    case Decl::ObjCProtocol:
3922d75d6f56c2937d67aecb6008793694f9eb51349Zhongxing Xu    case Decl::ObjCImplementation:
3932d75d6f56c2937d67aecb6008793694f9eb51349Zhongxing Xu    case Decl::ObjCCategoryImpl:
3942d75d6f56c2937d67aecb6008793694f9eb51349Zhongxing Xu    case Decl::LinkageSpec:
3952d75d6f56c2937d67aecb6008793694f9eb51349Zhongxing Xu    case Decl::Block:
3962d75d6f56c2937d67aecb6008793694f9eb51349Zhongxing Xu    case Decl::Function:
3972d75d6f56c2937d67aecb6008793694f9eb51349Zhongxing Xu    case Decl::CXXMethod:
3982d75d6f56c2937d67aecb6008793694f9eb51349Zhongxing Xu    case Decl::CXXConstructor:
3992d75d6f56c2937d67aecb6008793694f9eb51349Zhongxing Xu    case Decl::CXXDestructor:
4002d75d6f56c2937d67aecb6008793694f9eb51349Zhongxing Xu    case Decl::CXXConversion:
4012d75d6f56c2937d67aecb6008793694f9eb51349Zhongxing Xu    {
402651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines      DeclContext* DC = cast<DeclContext>(I);
403071e4da10b07ca5278a7ce9dcabd853e0d57e5a4Mike Stump      PrintDeclContext(DC, Indentation+2);
4042d75d6f56c2937d67aecb6008793694f9eb51349Zhongxing Xu      break;
4052d75d6f56c2937d67aecb6008793694f9eb51349Zhongxing Xu    }
406a3d39c066521a76fb30c83c560ece9a18d296b20Francois Pichet    case Decl::IndirectField: {
407651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines      IndirectFieldDecl* IFD = cast<IndirectFieldDecl>(I);
408b8989f27f116ff2400e92a52c067a69846119eb5Benjamin Kramer      Out << "<IndirectField> " << *IFD << '\n';
409a3d39c066521a76fb30c83c560ece9a18d296b20Francois Pichet      break;
410a3d39c066521a76fb30c83c560ece9a18d296b20Francois Pichet    }
41121ac10d5e6f8781b498ed0338af435c117bd27d8Chris Lattner    case Decl::Label: {
412651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines      LabelDecl *LD = cast<LabelDecl>(I);
413b8989f27f116ff2400e92a52c067a69846119eb5Benjamin Kramer      Out << "<Label> " << *LD << '\n';
41421ac10d5e6f8781b498ed0338af435c117bd27d8Chris Lattner      break;
41521ac10d5e6f8781b498ed0338af435c117bd27d8Chris Lattner    }
4162d75d6f56c2937d67aecb6008793694f9eb51349Zhongxing Xu    case Decl::Field: {
417651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines      FieldDecl *FD = cast<FieldDecl>(I);
418b8989f27f116ff2400e92a52c067a69846119eb5Benjamin Kramer      Out << "<field> " << *FD << '\n';
4192d75d6f56c2937d67aecb6008793694f9eb51349Zhongxing Xu      break;
4202d75d6f56c2937d67aecb6008793694f9eb51349Zhongxing Xu    }
421162e1c1b487352434552147967c3dd296ebee2f7Richard Smith    case Decl::Typedef:
422162e1c1b487352434552147967c3dd296ebee2f7Richard Smith    case Decl::TypeAlias: {
423651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines      TypedefNameDecl* TD = cast<TypedefNameDecl>(I);
424b8989f27f116ff2400e92a52c067a69846119eb5Benjamin Kramer      Out << "<typedef> " << *TD << '\n';
4252d75d6f56c2937d67aecb6008793694f9eb51349Zhongxing Xu      break;
4262d75d6f56c2937d67aecb6008793694f9eb51349Zhongxing Xu    }
4272d75d6f56c2937d67aecb6008793694f9eb51349Zhongxing Xu    case Decl::EnumConstant: {
428651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines      EnumConstantDecl* ECD = cast<EnumConstantDecl>(I);
429b8989f27f116ff2400e92a52c067a69846119eb5Benjamin Kramer      Out << "<enum constant> " << *ECD << '\n';
4302d75d6f56c2937d67aecb6008793694f9eb51349Zhongxing Xu      break;
4312d75d6f56c2937d67aecb6008793694f9eb51349Zhongxing Xu    }
4322d75d6f56c2937d67aecb6008793694f9eb51349Zhongxing Xu    case Decl::Var: {
433651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines      VarDecl* VD = cast<VarDecl>(I);
434b8989f27f116ff2400e92a52c067a69846119eb5Benjamin Kramer      Out << "<var> " << *VD << '\n';
4352d75d6f56c2937d67aecb6008793694f9eb51349Zhongxing Xu      break;
4362d75d6f56c2937d67aecb6008793694f9eb51349Zhongxing Xu    }
4372d75d6f56c2937d67aecb6008793694f9eb51349Zhongxing Xu    case Decl::ImplicitParam: {
438651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines      ImplicitParamDecl* IPD = cast<ImplicitParamDecl>(I);
439b8989f27f116ff2400e92a52c067a69846119eb5Benjamin Kramer      Out << "<implicit parameter> " << *IPD << '\n';
4402d75d6f56c2937d67aecb6008793694f9eb51349Zhongxing Xu      break;
4412d75d6f56c2937d67aecb6008793694f9eb51349Zhongxing Xu    }
4422d75d6f56c2937d67aecb6008793694f9eb51349Zhongxing Xu    case Decl::ParmVar: {
443651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines      ParmVarDecl* PVD = cast<ParmVarDecl>(I);
444b8989f27f116ff2400e92a52c067a69846119eb5Benjamin Kramer      Out << "<parameter> " << *PVD << '\n';
4452d75d6f56c2937d67aecb6008793694f9eb51349Zhongxing Xu      break;
4462d75d6f56c2937d67aecb6008793694f9eb51349Zhongxing Xu    }
4472d75d6f56c2937d67aecb6008793694f9eb51349Zhongxing Xu    case Decl::ObjCProperty: {
448651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines      ObjCPropertyDecl* OPD = cast<ObjCPropertyDecl>(I);
449b8989f27f116ff2400e92a52c067a69846119eb5Benjamin Kramer      Out << "<objc property> " << *OPD << '\n';
4502d75d6f56c2937d67aecb6008793694f9eb51349Zhongxing Xu      break;
4512d75d6f56c2937d67aecb6008793694f9eb51349Zhongxing Xu    }
4527ac1c9ef0bd250da82ddf3f5213182278e351753Eli Friedman    case Decl::FunctionTemplate: {
453651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines      FunctionTemplateDecl* FTD = cast<FunctionTemplateDecl>(I);
454b8989f27f116ff2400e92a52c067a69846119eb5Benjamin Kramer      Out << "<function template> " << *FTD << '\n';
4557ac1c9ef0bd250da82ddf3f5213182278e351753Eli Friedman      break;
4567ac1c9ef0bd250da82ddf3f5213182278e351753Eli Friedman    }
457368a55d3ce5d66c6d0502c6f8bf061c06961042cEli Friedman    case Decl::FileScopeAsm: {
458368a55d3ce5d66c6d0502c6f8bf061c06961042cEli Friedman      Out << "<file-scope asm>\n";
459368a55d3ce5d66c6d0502c6f8bf061c06961042cEli Friedman      break;
460368a55d3ce5d66c6d0502c6f8bf061c06961042cEli Friedman    }
461368a55d3ce5d66c6d0502c6f8bf061c06961042cEli Friedman    case Decl::UsingDirective: {
462368a55d3ce5d66c6d0502c6f8bf061c06961042cEli Friedman      Out << "<using directive>\n";
463368a55d3ce5d66c6d0502c6f8bf061c06961042cEli Friedman      break;
464368a55d3ce5d66c6d0502c6f8bf061c06961042cEli Friedman    }
465368a55d3ce5d66c6d0502c6f8bf061c06961042cEli Friedman    case Decl::NamespaceAlias: {
466651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines      NamespaceAliasDecl* NAD = cast<NamespaceAliasDecl>(I);
467b8989f27f116ff2400e92a52c067a69846119eb5Benjamin Kramer      Out << "<namespace alias> " << *NAD << '\n';
468368a55d3ce5d66c6d0502c6f8bf061c06961042cEli Friedman      break;
469368a55d3ce5d66c6d0502c6f8bf061c06961042cEli Friedman    }
4702f3cd9cb830aba522ad5d6884c0dab23770609a2Zhongxing Xu    case Decl::ClassTemplate: {
471651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines      ClassTemplateDecl *CTD = cast<ClassTemplateDecl>(I);
472b8989f27f116ff2400e92a52c067a69846119eb5Benjamin Kramer      Out << "<class template> " << *CTD << '\n';
4732f3cd9cb830aba522ad5d6884c0dab23770609a2Zhongxing Xu      break;
4742f3cd9cb830aba522ad5d6884c0dab23770609a2Zhongxing Xu    }
475c640058aa7f224a71ce3b1d2601d84e1b57f82d3Alexey Bataev    case Decl::OMPThreadPrivate: {
476651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines      Out << "<omp threadprivate> " << '"' << I << "\"\n";
477c640058aa7f224a71ce3b1d2601d84e1b57f82d3Alexey Bataev      break;
478c640058aa7f224a71ce3b1d2601d84e1b57f82d3Alexey Bataev    }
4792d75d6f56c2937d67aecb6008793694f9eb51349Zhongxing Xu    default:
480651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines      Out << "DeclKind: " << DK << '"' << I << "\"\n";
481b219cfc4d75f0a03630b7c4509ef791b7e97b2c8David Blaikie      llvm_unreachable("decl unhandled");
4822d75d6f56c2937d67aecb6008793694f9eb51349Zhongxing Xu    }
4832d75d6f56c2937d67aecb6008793694f9eb51349Zhongxing Xu  }
4842d75d6f56c2937d67aecb6008793694f9eb51349Zhongxing Xu}
485176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hinesstd::unique_ptr<ASTConsumer> clang::CreateDeclContextPrinter() {
486176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines  return llvm::make_unique<DeclContextPrinter>();
4872d75d6f56c2937d67aecb6008793694f9eb51349Zhongxing Xu}
488