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