aboutsummaryrefslogtreecommitdiff
path: root/contrib/llvm-project/clang/lib/Frontend/ASTConsumers.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'contrib/llvm-project/clang/lib/Frontend/ASTConsumers.cpp')
-rw-r--r--contrib/llvm-project/clang/lib/Frontend/ASTConsumers.cpp214
1 files changed, 214 insertions, 0 deletions
diff --git a/contrib/llvm-project/clang/lib/Frontend/ASTConsumers.cpp b/contrib/llvm-project/clang/lib/Frontend/ASTConsumers.cpp
new file mode 100644
index 000000000000..a73cc8876d5d
--- /dev/null
+++ b/contrib/llvm-project/clang/lib/Frontend/ASTConsumers.cpp
@@ -0,0 +1,214 @@
+//===--- ASTConsumers.cpp - ASTConsumer implementations -------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+//
+// AST Consumer Implementations.
+//
+//===----------------------------------------------------------------------===//
+
+#include "clang/Frontend/ASTConsumers.h"
+#include "clang/AST/AST.h"
+#include "clang/AST/ASTConsumer.h"
+#include "clang/AST/ASTContext.h"
+#include "clang/AST/PrettyPrinter.h"
+#include "clang/AST/RecordLayout.h"
+#include "clang/AST/RecursiveASTVisitor.h"
+#include "clang/Basic/Diagnostic.h"
+#include "clang/Basic/SourceManager.h"
+#include "llvm/Support/Path.h"
+#include "llvm/Support/Timer.h"
+#include "llvm/Support/raw_ostream.h"
+using namespace clang;
+
+//===----------------------------------------------------------------------===//
+/// ASTPrinter - Pretty-printer and dumper of ASTs
+
+namespace {
+ class ASTPrinter : public ASTConsumer,
+ public RecursiveASTVisitor<ASTPrinter> {
+ typedef RecursiveASTVisitor<ASTPrinter> base;
+
+ public:
+ enum Kind { DumpFull, Dump, Print, None };
+ ASTPrinter(std::unique_ptr<raw_ostream> Out, Kind K,
+ ASTDumpOutputFormat Format, StringRef FilterString,
+ bool DumpLookups = false, bool DumpDeclTypes = false)
+ : Out(Out ? *Out : llvm::outs()), OwnedOut(std::move(Out)),
+ OutputKind(K), OutputFormat(Format), FilterString(FilterString),
+ DumpLookups(DumpLookups), DumpDeclTypes(DumpDeclTypes) {}
+
+ void HandleTranslationUnit(ASTContext &Context) override {
+ TranslationUnitDecl *D = Context.getTranslationUnitDecl();
+
+ if (FilterString.empty())
+ return print(D);
+
+ TraverseDecl(D);
+ }
+
+ bool shouldWalkTypesOfTypeLocs() const { return false; }
+
+ bool TraverseDecl(Decl *D) {
+ if (D && filterMatches(D)) {
+ bool ShowColors = Out.has_colors();
+ if (ShowColors)
+ Out.changeColor(raw_ostream::BLUE);
+ Out << (OutputKind != Print ? "Dumping " : "Printing ") << getName(D)
+ << ":\n";
+ if (ShowColors)
+ Out.resetColor();
+ print(D);
+ Out << "\n";
+ // Don't traverse child nodes to avoid output duplication.
+ return true;
+ }
+ return base::TraverseDecl(D);
+ }
+
+ private:
+ std::string getName(Decl *D) {
+ if (isa<NamedDecl>(D))
+ return cast<NamedDecl>(D)->getQualifiedNameAsString();
+ return "";
+ }
+ bool filterMatches(Decl *D) {
+ return getName(D).find(FilterString) != std::string::npos;
+ }
+ void print(Decl *D) {
+ if (DumpLookups) {
+ if (DeclContext *DC = dyn_cast<DeclContext>(D)) {
+ if (DC == DC->getPrimaryContext())
+ DC->dumpLookups(Out, OutputKind != None, OutputKind == DumpFull);
+ else
+ Out << "Lookup map is in primary DeclContext "
+ << DC->getPrimaryContext() << "\n";
+ } else
+ Out << "Not a DeclContext\n";
+ } else if (OutputKind == Print) {
+ PrintingPolicy Policy(D->getASTContext().getLangOpts());
+ D->print(Out, Policy, /*Indentation=*/0, /*PrintInstantiation=*/true);
+ } else if (OutputKind != None) {
+ D->dump(Out, OutputKind == DumpFull, OutputFormat);
+ }
+
+ if (DumpDeclTypes) {
+ Decl *InnerD = D;
+ if (auto *TD = dyn_cast<TemplateDecl>(D))
+ InnerD = TD->getTemplatedDecl();
+
+ // FIXME: Support OutputFormat in type dumping.
+ // FIXME: Support combining -ast-dump-decl-types with -ast-dump-lookups.
+ if (auto *VD = dyn_cast<ValueDecl>(InnerD))
+ VD->getType().dump(Out, VD->getASTContext());
+ if (auto *TD = dyn_cast<TypeDecl>(InnerD))
+ TD->getTypeForDecl()->dump(Out, TD->getASTContext());
+ }
+ }
+
+ raw_ostream &Out;
+ std::unique_ptr<raw_ostream> OwnedOut;
+
+ /// How to output individual declarations.
+ Kind OutputKind;
+
+ /// What format should the output take?
+ ASTDumpOutputFormat OutputFormat;
+
+ /// Which declarations or DeclContexts to display.
+ std::string FilterString;
+
+ /// Whether the primary output is lookup results or declarations. Individual
+ /// results will be output with a format determined by OutputKind. This is
+ /// incompatible with OutputKind == Print.
+ bool DumpLookups;
+
+ /// Whether to dump the type for each declaration dumped.
+ bool DumpDeclTypes;
+ };
+
+ class ASTDeclNodeLister : public ASTConsumer,
+ public RecursiveASTVisitor<ASTDeclNodeLister> {
+ public:
+ ASTDeclNodeLister(raw_ostream *Out = nullptr)
+ : Out(Out ? *Out : llvm::outs()) {}
+
+ void HandleTranslationUnit(ASTContext &Context) override {
+ TraverseDecl(Context.getTranslationUnitDecl());
+ }
+
+ bool shouldWalkTypesOfTypeLocs() const { return false; }
+
+ bool VisitNamedDecl(NamedDecl *D) {
+ D->printQualifiedName(Out);
+ Out << '\n';
+ return true;
+ }
+
+ private:
+ raw_ostream &Out;
+ };
+} // end anonymous namespace
+
+std::unique_ptr<ASTConsumer>
+clang::CreateASTPrinter(std::unique_ptr<raw_ostream> Out,
+ StringRef FilterString) {
+ return std::make_unique<ASTPrinter>(std::move(Out), ASTPrinter::Print,
+ ADOF_Default, FilterString);
+}
+
+std::unique_ptr<ASTConsumer>
+clang::CreateASTDumper(std::unique_ptr<raw_ostream> Out, StringRef FilterString,
+ bool DumpDecls, bool Deserialize, bool DumpLookups,
+ bool DumpDeclTypes, ASTDumpOutputFormat Format) {
+ assert((DumpDecls || Deserialize || DumpLookups) && "nothing to dump");
+ return std::make_unique<ASTPrinter>(
+ std::move(Out),
+ Deserialize ? ASTPrinter::DumpFull
+ : DumpDecls ? ASTPrinter::Dump : ASTPrinter::None,
+ Format, FilterString, DumpLookups, DumpDeclTypes);
+}
+
+std::unique_ptr<ASTConsumer> clang::CreateASTDeclNodeLister() {
+ return std::make_unique<ASTDeclNodeLister>(nullptr);
+}
+
+//===----------------------------------------------------------------------===//
+/// ASTViewer - AST Visualization
+
+namespace {
+ class ASTViewer : public ASTConsumer {
+ ASTContext *Context;
+ public:
+ void Initialize(ASTContext &Context) override {
+ this->Context = &Context;
+ }
+
+ bool HandleTopLevelDecl(DeclGroupRef D) override {
+ for (DeclGroupRef::iterator I = D.begin(), E = D.end(); I != E; ++I)
+ HandleTopLevelSingleDecl(*I);
+ return true;
+ }
+
+ void HandleTopLevelSingleDecl(Decl *D);
+ };
+}
+
+void ASTViewer::HandleTopLevelSingleDecl(Decl *D) {
+ if (isa<FunctionDecl>(D) || isa<ObjCMethodDecl>(D)) {
+ D->print(llvm::errs());
+
+ if (Stmt *Body = D->getBody()) {
+ llvm::errs() << '\n';
+ Body->viewAST();
+ llvm::errs() << '\n';
+ }
+ }
+}
+
+std::unique_ptr<ASTConsumer> clang::CreateASTViewer() {
+ return std::make_unique<ASTViewer>();
+}