1 //===-- ASTDumper.cpp -------------------------------------------*- C++ -*-===//
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 #include "ASTDumper.h"
11 
12 #include "lldb/Symbol/ClangASTContext.h"
13 #include "lldb/Symbol/ClangUtil.h"
14 #include "lldb/Symbol/CompilerType.h"
15 #include "lldb/Utility/Log.h"
16 
17 #include "llvm/Support/raw_ostream.h"
18 
19 using namespace lldb_private;
20 
ASTDumper(clang::Decl * decl)21 ASTDumper::ASTDumper(clang::Decl *decl) {
22   clang::DeclContext *decl_ctx = llvm::dyn_cast<clang::DeclContext>(decl);
23 
24   bool has_external_lexical_storage;
25   bool has_external_visible_storage;
26 
27   if (decl_ctx) {
28     has_external_lexical_storage = decl_ctx->hasExternalLexicalStorage();
29     has_external_visible_storage = decl_ctx->hasExternalVisibleStorage();
30     decl_ctx->setHasExternalLexicalStorage(false);
31     decl_ctx->setHasExternalVisibleStorage(false);
32   }
33 
34   llvm::raw_string_ostream os(m_dump);
35   decl->print(os);
36   os.flush();
37 
38   if (decl_ctx) {
39     decl_ctx->setHasExternalLexicalStorage(has_external_lexical_storage);
40     decl_ctx->setHasExternalVisibleStorage(has_external_visible_storage);
41   }
42 }
43 
ASTDumper(clang::DeclContext * decl_ctx)44 ASTDumper::ASTDumper(clang::DeclContext *decl_ctx) {
45   bool has_external_lexical_storage = decl_ctx->hasExternalLexicalStorage();
46   bool has_external_visible_storage = decl_ctx->hasExternalVisibleStorage();
47 
48   decl_ctx->setHasExternalLexicalStorage(false);
49   decl_ctx->setHasExternalVisibleStorage(false);
50 
51   if (clang::Decl *decl = llvm::dyn_cast<clang::Decl>(decl_ctx)) {
52     llvm::raw_string_ostream os(m_dump);
53     decl->print(os);
54     os.flush();
55   } else {
56     m_dump.assign("<DeclContext is not a Decl>");
57   }
58 
59   decl_ctx->setHasExternalLexicalStorage(has_external_lexical_storage);
60   decl_ctx->setHasExternalVisibleStorage(has_external_visible_storage);
61 }
62 
ASTDumper(const clang::Type * type)63 ASTDumper::ASTDumper(const clang::Type *type) {
64   m_dump = clang::QualType(type, 0).getAsString();
65 }
66 
ASTDumper(clang::QualType type)67 ASTDumper::ASTDumper(clang::QualType type) { m_dump = type.getAsString(); }
68 
ASTDumper(lldb::opaque_compiler_type_t type)69 ASTDumper::ASTDumper(lldb::opaque_compiler_type_t type) {
70   m_dump = clang::QualType::getFromOpaquePtr(type).getAsString();
71 }
72 
ASTDumper(const CompilerType & compiler_type)73 ASTDumper::ASTDumper(const CompilerType &compiler_type) {
74   m_dump = ClangUtil::GetQualType(compiler_type).getAsString();
75 }
76 
GetCString()77 const char *ASTDumper::GetCString() { return m_dump.c_str(); }
78 
ToSTDERR()79 void ASTDumper::ToSTDERR() { fprintf(stderr, "%s\n", m_dump.c_str()); }
80 
ToLog(Log * log,const char * prefix)81 void ASTDumper::ToLog(Log *log, const char *prefix) {
82   size_t len = m_dump.length() + 1;
83 
84   char *alloc = (char *)malloc(len);
85   char *str = alloc;
86 
87   memcpy(str, m_dump.c_str(), len);
88 
89   char *end = NULL;
90 
91   end = strchr(str, '\n');
92 
93   while (end) {
94     *end = '\0';
95 
96     log->Printf("%s%s", prefix, str);
97 
98     *end = '\n';
99 
100     str = end + 1;
101     end = strchr(str, '\n');
102   }
103 
104   log->Printf("%s%s", prefix, str);
105 
106   free(alloc);
107 }
108 
ToStream(lldb::StreamSP & stream)109 void ASTDumper::ToStream(lldb::StreamSP &stream) { stream->PutCString(m_dump); }
110