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