blob: 84a97c8e5df40299696e3ee79863b2f7443d2f10 [file] [log] [blame]
Sean Callanan65dafa82010-08-27 01:01:44 +00001//===-- ASTStructExtractor.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 "stdlib.h"
11#include "clang/AST/ASTContext.h"
12#include "clang/AST/Decl.h"
13#include "clang/AST/DeclCXX.h"
14#include "clang/AST/DeclGroup.h"
15#include "clang/AST/Expr.h"
16#include "clang/AST/RecordLayout.h"
17#include "clang/AST/Stmt.h"
18#include "clang/Parse/Action.h"
19#include "clang/Parse/Parser.h"
20#include "clang/Parse/Scope.h"
21#include "llvm/Support/Casting.h"
22#include "llvm/Support/raw_ostream.h"
23#include "lldb/Core/Log.h"
24#include "lldb/Expression/ASTStructExtractor.h"
25
26using namespace llvm;
27using namespace clang;
28using namespace lldb_private;
29
30ASTStructExtractor::ASTStructExtractor(ASTConsumer *passthrough,
31 const char *struct_name,
32 ClangFunction &function) :
33 m_ast_context (NULL),
34 m_passthrough (passthrough),
35 m_passthrough_sema (NULL),
36 m_sema (NULL),
37 m_action (NULL),
38 m_struct_name (struct_name),
39 m_function (function)
40{
41 if (!m_passthrough)
42 return;
43
44 m_passthrough_sema = dyn_cast<SemaConsumer>(passthrough);
45}
46
47ASTStructExtractor::~ASTStructExtractor()
48{
49}
50
51void
52ASTStructExtractor::Initialize(ASTContext &Context)
53{
54 m_ast_context = &Context;
55
56 if (m_passthrough)
57 m_passthrough->Initialize(Context);
58}
59
60void
61ASTStructExtractor::ExtractFromFunctionDecl(FunctionDecl *F)
62{
63 DeclarationName struct_name(&m_ast_context->Idents.get(m_struct_name.c_str()));
64 RecordDecl::lookup_result struct_lookup = F->lookup(struct_name);
65
66 if (struct_lookup.first == struct_lookup.second)
67 return;
68
69 RecordDecl *struct_decl = dyn_cast<RecordDecl>(*(struct_lookup.first));
70
71 if (!struct_decl)
72 return;
73
74 const ASTRecordLayout* struct_layout(&m_ast_context->getASTRecordLayout (struct_decl));
75
76 if (!struct_layout)
77 return;
78
79 m_function.m_struct_size = struct_layout->getSize() / 8; // Clang returns sizes in bits.
80 m_function.m_return_offset = struct_layout->getFieldOffset(struct_layout->getFieldCount() - 1) / 8;
81 m_function.m_return_size = (struct_layout->getDataSize() / 8) - m_function.m_return_offset;
82
83 for (unsigned field_index = 0, num_fields = struct_layout->getFieldCount();
84 field_index < num_fields;
85 ++field_index)
86 {
87 m_function.m_member_offsets.push_back(struct_layout->getFieldOffset(field_index) / 8);
88 }
89
90 m_function.m_struct_valid = true;
91}
92
93void
94ASTStructExtractor::ExtractFromTopLevelDecl(Decl* D)
95{
96 LinkageSpecDecl *linkage_spec_decl = dyn_cast<LinkageSpecDecl>(D);
97
98 if (linkage_spec_decl)
99 {
100 RecordDecl::decl_iterator decl_iterator;
101
102 for (decl_iterator = linkage_spec_decl->decls_begin();
103 decl_iterator != linkage_spec_decl->decls_end();
104 ++decl_iterator)
105 {
106 ExtractFromTopLevelDecl(*decl_iterator);
107 }
108 }
109
110 FunctionDecl *function_decl = dyn_cast<FunctionDecl>(D);
111
112 if (m_ast_context &&
113 function_decl &&
114 !m_function.m_wrapper_function_name.compare(function_decl->getNameAsCString()))
115 {
116 ExtractFromFunctionDecl(function_decl);
117 }
118}
119
120void
121ASTStructExtractor::HandleTopLevelDecl(DeclGroupRef D)
122{
123 DeclGroupRef::iterator decl_iterator;
124
125 for (decl_iterator = D.begin();
126 decl_iterator != D.end();
127 ++decl_iterator)
128 {
129 Decl *decl = *decl_iterator;
130
131 ExtractFromTopLevelDecl(decl);
132 }
133
134 if (m_passthrough)
135 m_passthrough->HandleTopLevelDecl(D);
136}
137
138void
139ASTStructExtractor::HandleTranslationUnit(ASTContext &Ctx)
140{
141 if (m_passthrough)
142 m_passthrough->HandleTranslationUnit(Ctx);
143}
144
145void
146ASTStructExtractor::HandleTagDeclDefinition(TagDecl *D)
147{
148 if (m_passthrough)
149 m_passthrough->HandleTagDeclDefinition(D);
150}
151
152void
153ASTStructExtractor::CompleteTentativeDefinition(VarDecl *D)
154{
155 if (m_passthrough)
156 m_passthrough->CompleteTentativeDefinition(D);
157}
158
159void
160ASTStructExtractor::HandleVTable(CXXRecordDecl *RD, bool DefinitionRequired)
161{
162 if (m_passthrough)
163 m_passthrough->HandleVTable(RD, DefinitionRequired);
164}
165
166void
167ASTStructExtractor::PrintStats()
168{
169 if (m_passthrough)
170 m_passthrough->PrintStats();
171}
172
173void
174ASTStructExtractor::InitializeSema(Sema &S)
175{
176 m_sema = &S;
177 m_action = reinterpret_cast<Action*>(m_sema);
178
179 if (m_passthrough_sema)
180 m_passthrough_sema->InitializeSema(S);
181}
182
183void
184ASTStructExtractor::ForgetSema()
185{
186 m_sema = NULL;
187 m_action = NULL;
188
189 if (m_passthrough_sema)
190 m_passthrough_sema->ForgetSema();
191}