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