blob: 738b342d5e88aaa6b2b12441e696628617db249f [file] [log] [blame]
Greg Clayton1e591ce2010-07-16 18:28:27 +00001//===-- ClangASTSource.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
Chris Lattner24943d22010-06-08 16:52:24 +000010
Chris Lattner24943d22010-06-08 16:52:24 +000011#include "clang/AST/ASTContext.h"
Sean Callanan8f2e3922012-02-04 08:49:35 +000012#include "clang/AST/RecordLayout.h"
Greg Claytonf4c7ae02010-10-15 03:36:13 +000013#include "lldb/Core/Log.h"
Greg Clayton6e0101c2011-09-17 06:21:20 +000014#include "lldb/Core/Module.h"
Sean Callanan73b520f2011-10-29 01:58:46 +000015#include "lldb/Core/ModuleList.h"
Sean Callananbb715f92011-10-29 02:28:18 +000016#include "lldb/Expression/ASTDumper.h"
Chris Lattner24943d22010-06-08 16:52:24 +000017#include "lldb/Expression/ClangASTSource.h"
18#include "lldb/Expression/ClangExpression.h"
Sean Callanan73b520f2011-10-29 01:58:46 +000019#include "lldb/Symbol/ClangNamespaceDecl.h"
20#include "lldb/Symbol/SymbolVendor.h"
Sean Callanan673f3db2011-11-30 22:11:59 +000021#include "lldb/Target/ObjCLanguageRuntime.h"
Sean Callanan73b520f2011-10-29 01:58:46 +000022#include "lldb/Target/Target.h"
Chris Lattner24943d22010-06-08 16:52:24 +000023
24using namespace clang;
25using namespace lldb_private;
26
Greg Claytonb01000f2011-01-17 03:46:26 +000027ClangASTSource::~ClangASTSource()
28{
Sean Callanana3d04472011-11-29 00:42:02 +000029 m_ast_importer->ForgetDestination(m_ast_context);
30
Johnny Chenfa21ffd2011-11-30 23:18:53 +000031 // We are in the process of destruction, don't create clang ast context on demand
32 // by passing false to Target::GetScratchClangASTContext(create_on_demand).
33 ClangASTContext *scratch_clang_ast_context = m_target->GetScratchClangASTContext(false);
Sean Callanana3d04472011-11-29 00:42:02 +000034
35 if (!scratch_clang_ast_context)
36 return;
37
38 clang::ASTContext *scratch_ast_context = scratch_clang_ast_context->getASTContext();
39
40 if (!scratch_ast_context)
41 return;
42
43 if (m_ast_context != scratch_ast_context)
44 m_ast_importer->ForgetSource(scratch_ast_context, m_ast_context);
Greg Claytonb01000f2011-01-17 03:46:26 +000045}
Chris Lattner24943d22010-06-08 16:52:24 +000046
Greg Claytonb01000f2011-01-17 03:46:26 +000047void
48ClangASTSource::StartTranslationUnit(ASTConsumer *Consumer)
49{
Sean Callananf76afff2011-10-28 23:38:38 +000050 if (!m_ast_context)
51 return;
52
53 m_ast_context->getTranslationUnitDecl()->setHasExternalVisibleStorage();
54 m_ast_context->getTranslationUnitDecl()->setHasExternalLexicalStorage();
Chris Lattner24943d22010-06-08 16:52:24 +000055}
56
Chris Lattner24943d22010-06-08 16:52:24 +000057// The core lookup interface.
Greg Claytonb01000f2011-01-17 03:46:26 +000058DeclContext::lookup_result
59ClangASTSource::FindExternalVisibleDeclsByName
Greg Claytonf4c7ae02010-10-15 03:36:13 +000060(
61 const DeclContext *decl_ctx,
Greg Clayton8de27c72010-10-15 22:48:33 +000062 DeclarationName clang_decl_name
Greg Claytonf4c7ae02010-10-15 03:36:13 +000063)
64{
Sean Callananf76afff2011-10-28 23:38:38 +000065 if (!m_ast_context)
66 return SetNoExternalVisibleDeclsForName(decl_ctx, clang_decl_name);
67
68 if (GetImportInProgress())
Greg Claytonb01000f2011-01-17 03:46:26 +000069 return SetNoExternalVisibleDeclsForName(decl_ctx, clang_decl_name);
70
71 std::string decl_name (clang_decl_name.getAsString());
72
73// if (m_decl_map.DoingASTImport ())
74// return DeclContext::lookup_result();
75//
Greg Clayton8de27c72010-10-15 22:48:33 +000076 switch (clang_decl_name.getNameKind()) {
Chris Lattner24943d22010-06-08 16:52:24 +000077 // Normal identifiers.
78 case DeclarationName::Identifier:
Greg Clayton8de27c72010-10-15 22:48:33 +000079 if (clang_decl_name.getAsIdentifierInfo()->getBuiltinID() != 0)
80 return SetNoExternalVisibleDeclsForName(decl_ctx, clang_decl_name);
81 break;
Chris Lattner24943d22010-06-08 16:52:24 +000082
83 // Operator names. Not important for now.
84 case DeclarationName::CXXOperatorName:
85 case DeclarationName::CXXLiteralOperatorName:
86 return DeclContext::lookup_result();
87
88 // Using directives found in this context.
89 // Tell Sema we didn't find any or we'll end up getting asked a *lot*.
90 case DeclarationName::CXXUsingDirective:
Greg Clayton8de27c72010-10-15 22:48:33 +000091 return SetNoExternalVisibleDeclsForName(decl_ctx, clang_decl_name);
Chris Lattner24943d22010-06-08 16:52:24 +000092
Chris Lattner24943d22010-06-08 16:52:24 +000093 case DeclarationName::ObjCZeroArgSelector:
94 case DeclarationName::ObjCOneArgSelector:
95 case DeclarationName::ObjCMultiArgSelector:
Sean Callanan9b714842011-11-09 19:33:21 +000096 {
97 llvm::SmallVector<NamedDecl*, 1> method_decls;
Chris Lattner24943d22010-06-08 16:52:24 +000098
Sean Callanan9b714842011-11-09 19:33:21 +000099 NameSearchContext method_search_context (*this, method_decls, clang_decl_name, decl_ctx);
100
101 FindObjCMethodDecls(method_search_context);
102
103 return SetExternalVisibleDeclsForName (decl_ctx, clang_decl_name, method_decls);
104 }
Chris Lattner24943d22010-06-08 16:52:24 +0000105 // These aren't possible in the global context.
106 case DeclarationName::CXXConstructorName:
107 case DeclarationName::CXXDestructorName:
108 case DeclarationName::CXXConversionFunctionName:
109 return DeclContext::lookup_result();
110 }
Greg Claytonf4c7ae02010-10-15 03:36:13 +0000111
Greg Claytonf4c7ae02010-10-15 03:36:13 +0000112
Sean Callananf76afff2011-10-28 23:38:38 +0000113 if (!GetLookupsEnabled())
Greg Clayton8de27c72010-10-15 22:48:33 +0000114 {
115 // Wait until we see a '$' at the start of a name before we start doing
116 // any lookups so we can avoid lookup up all of the builtin types.
117 if (!decl_name.empty() && decl_name[0] == '$')
118 {
Sean Callananf76afff2011-10-28 23:38:38 +0000119 SetLookupsEnabled (true);
Greg Clayton8de27c72010-10-15 22:48:33 +0000120 }
121 else
122 {
123 return SetNoExternalVisibleDeclsForName(decl_ctx, clang_decl_name);
124 }
Greg Claytonf4c7ae02010-10-15 03:36:13 +0000125 }
Greg Clayton8de27c72010-10-15 22:48:33 +0000126
Greg Clayton8de27c72010-10-15 22:48:33 +0000127 ConstString const_decl_name(decl_name.c_str());
Greg Clayton9ceed1e2010-11-13 04:18:24 +0000128
129 const char *uniqued_const_decl_name = const_decl_name.GetCString();
130 if (m_active_lookups.find (uniqued_const_decl_name) != m_active_lookups.end())
131 {
132 // We are currently looking up this name...
133 return DeclContext::lookup_result();
134 }
135 m_active_lookups.insert(uniqued_const_decl_name);
Greg Claytona8b278a2010-11-15 01:34:18 +0000136// static uint32_t g_depth = 0;
137// ++g_depth;
138// printf("[%5u] FindExternalVisibleDeclsByName() \"%s\"\n", g_depth, uniqued_const_decl_name);
Greg Clayton9ceed1e2010-11-13 04:18:24 +0000139 llvm::SmallVector<NamedDecl*, 4> name_decls;
140 NameSearchContext name_search_context(*this, name_decls, clang_decl_name, decl_ctx);
Sean Callananf76afff2011-10-28 23:38:38 +0000141 FindExternalVisibleDecls(name_search_context);
Greg Clayton9ceed1e2010-11-13 04:18:24 +0000142 DeclContext::lookup_result result (SetExternalVisibleDeclsForName (decl_ctx, clang_decl_name, name_decls));
Greg Claytona8b278a2010-11-15 01:34:18 +0000143// --g_depth;
Greg Clayton9ceed1e2010-11-13 04:18:24 +0000144 m_active_lookups.erase (uniqued_const_decl_name);
145 return result;
Chris Lattner24943d22010-06-08 16:52:24 +0000146}
147
Greg Claytonb01000f2011-01-17 03:46:26 +0000148void
149ClangASTSource::CompleteType (TagDecl *tag_decl)
Sean Callananbb715f92011-10-29 02:28:18 +0000150{
151 lldb::LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS));
152
Sean Callananb2027ec2011-12-08 23:45:45 +0000153 static unsigned int invocation_id = 0;
154 unsigned int current_id = invocation_id++;
155
Sean Callananbb715f92011-10-29 02:28:18 +0000156 if (log)
157 {
Sean Callanan6e22e8b2012-01-13 22:05:55 +0000158 log->Printf(" CompleteTagDecl[%u] on (ASTContext*)%p Completing (TagDecl*)%p named %s",
159 current_id,
Sean Callananb2027ec2011-12-08 23:45:45 +0000160 m_ast_context,
Sean Callanan6e22e8b2012-01-13 22:05:55 +0000161 tag_decl,
Sean Callananb2027ec2011-12-08 23:45:45 +0000162 tag_decl->getName().str().c_str());
163
164 log->Printf(" CTD[%u] Before:", current_id);
Sean Callananbb715f92011-10-29 02:28:18 +0000165 ASTDumper dumper((Decl*)tag_decl);
166 dumper.ToLog(log, " [CTD] ");
167 }
168
Sean Callananb2027ec2011-12-08 23:45:45 +0000169 if (!m_ast_importer->CompleteTagDecl (tag_decl))
170 {
171 // We couldn't complete the type. Maybe there's a definition
172 // somewhere else that can be completed.
173
174 if (log)
175 log->Printf(" CTD[%u] Type could not be completed in the module in which it was first found.", current_id);
176
177 bool found = false;
178
179 DeclContext *decl_ctx = tag_decl->getDeclContext();
180
181 if (const NamespaceDecl *namespace_context = dyn_cast<NamespaceDecl>(decl_ctx))
182 {
183 ClangASTImporter::NamespaceMapSP namespace_map = m_ast_importer->GetNamespaceMap(namespace_context);
184
185 if (log && log->GetVerbose())
186 log->Printf(" CTD[%u] Inspecting namespace map %p (%d entries)",
187 current_id,
188 namespace_map.get(),
189 (int)namespace_map->size());
190
191 if (!namespace_map)
192 return;
193
194 for (ClangASTImporter::NamespaceMap::iterator i = namespace_map->begin(), e = namespace_map->end();
195 i != e && !found;
196 ++i)
197 {
198 if (log)
199 log->Printf(" CTD[%u] Searching namespace %s in module %s",
200 current_id,
201 i->second.GetNamespaceDecl()->getNameAsString().c_str(),
202 i->first->GetFileSpec().GetFilename().GetCString());
203
204 TypeList types;
205
206 SymbolContext null_sc;
207 ConstString name(tag_decl->getName().str().c_str());
208
209 i->first->FindTypes(null_sc, name, &i->second, true, UINT32_MAX, types);
210
211 for (uint32_t ti = 0, te = types.GetSize();
212 ti != te && !found;
213 ++ti)
214 {
215 lldb::TypeSP type = types.GetTypeAtIndex(ti);
216
217 if (!type)
218 continue;
219
220 lldb::clang_type_t opaque_type = type->GetClangFullType();
221
222 if (!opaque_type)
223 continue;
224
Sean Callanan21f2e192011-12-14 01:13:04 +0000225 const TagType *tag_type = QualType::getFromOpaquePtr(opaque_type)->getAs<TagType>();
Sean Callananb2027ec2011-12-08 23:45:45 +0000226
227 if (!tag_type)
228 continue;
229
230 TagDecl *candidate_tag_decl = const_cast<TagDecl*>(tag_type->getDecl());
231
232 if (m_ast_importer->CompleteTagDeclWithOrigin (tag_decl, candidate_tag_decl))
233 found = true;
234 }
235 }
236 }
237 else
238 {
239 TypeList types;
240
241 SymbolContext null_sc;
242 ConstString name(tag_decl->getName().str().c_str());
243 ClangNamespaceDecl namespace_decl;
244
245 ModuleList &module_list = m_target->GetImages();
246
247 module_list.FindTypes(null_sc, name, true, UINT32_MAX, types);
248
249 for (uint32_t ti = 0, te = types.GetSize();
250 ti != te && !found;
251 ++ti)
252 {
253 lldb::TypeSP type = types.GetTypeAtIndex(ti);
254
255 if (!type)
256 continue;
257
258 lldb::clang_type_t opaque_type = type->GetClangFullType();
259
260 if (!opaque_type)
261 continue;
262
Sean Callanan21f2e192011-12-14 01:13:04 +0000263 const TagType *tag_type = QualType::getFromOpaquePtr(opaque_type)->getAs<TagType>();
Sean Callananb2027ec2011-12-08 23:45:45 +0000264
265 if (!tag_type)
266 continue;
267
268 TagDecl *candidate_tag_decl = const_cast<TagDecl*>(tag_type->getDecl());
269
270 if (m_ast_importer->CompleteTagDeclWithOrigin (tag_decl, candidate_tag_decl))
271 found = true;
272 }
273 }
274 }
Sean Callananbb715f92011-10-29 02:28:18 +0000275
276 if (log)
277 {
278 log->Printf(" [CTD] After:");
279 ASTDumper dumper((Decl*)tag_decl);
280 dumper.ToLog(log, " [CTD] ");
281 }
Greg Claytonb01000f2011-01-17 03:46:26 +0000282}
283
284void
Sean Callananbb715f92011-10-29 02:28:18 +0000285ClangASTSource::CompleteType (clang::ObjCInterfaceDecl *interface_decl)
286{
287 lldb::LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS));
288
289 if (log)
290 {
Sean Callanan5a55c7a2011-11-18 03:28:09 +0000291 log->Printf(" [CompleteObjCInterfaceDecl] on (ASTContext*)%p Completing an ObjCInterfaceDecl named %s", m_ast_context, interface_decl->getName().str().c_str());
Sean Callananbb715f92011-10-29 02:28:18 +0000292 log->Printf(" [COID] Before:");
293 ASTDumper dumper((Decl*)interface_decl);
294 dumper.ToLog(log, " [COID] ");
295 }
296
297 m_ast_importer->CompleteObjCInterfaceDecl (interface_decl);
298
299 if (log)
300 {
301 log->Printf(" [COID] After:");
302 ASTDumper dumper((Decl*)interface_decl);
303 dumper.ToLog(log, " [COID] ");
304 }
Greg Claytonb01000f2011-01-17 03:46:26 +0000305}
306
Sean Callanan9b6898f2011-07-30 02:42:06 +0000307clang::ExternalLoadResult
Sean Callananbb715f92011-10-29 02:28:18 +0000308ClangASTSource::FindExternalLexicalDecls (const DeclContext *decl_context,
309 bool (*predicate)(Decl::Kind),
310 llvm::SmallVectorImpl<Decl*> &decls)
311{
312 lldb::LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS));
313
314 const Decl *context_decl = dyn_cast<Decl>(decl_context);
315
316 if (!context_decl)
317 return ELR_Failure;
318
319 static unsigned int invocation_id = 0;
320 unsigned int current_id = invocation_id++;
321
322 if (log)
323 {
324 if (const NamedDecl *context_named_decl = dyn_cast<NamedDecl>(context_decl))
Sean Callanan5a55c7a2011-11-18 03:28:09 +0000325 log->Printf("FindExternalLexicalDecls[%u] on (ASTContext*)%p in '%s' (%sDecl*)%p with %s predicate",
Sean Callananbb715f92011-10-29 02:28:18 +0000326 current_id,
Sean Callanan5a55c7a2011-11-18 03:28:09 +0000327 m_ast_context,
Sean Callananbb715f92011-10-29 02:28:18 +0000328 context_named_decl->getNameAsString().c_str(),
Sean Callanan5a55c7a2011-11-18 03:28:09 +0000329 context_decl->getDeclKindName(),
330 context_decl,
Sean Callananbb715f92011-10-29 02:28:18 +0000331 (predicate ? "non-null" : "null"));
332 else if(context_decl)
Sean Callanan5a55c7a2011-11-18 03:28:09 +0000333 log->Printf("FindExternalLexicalDecls[%u] on (ASTContext*)%p in (%sDecl*)%p with %s predicate",
Sean Callananbb715f92011-10-29 02:28:18 +0000334 current_id,
Sean Callanan5a55c7a2011-11-18 03:28:09 +0000335 m_ast_context,
Sean Callananbb715f92011-10-29 02:28:18 +0000336 context_decl->getDeclKindName(),
Sean Callanan5a55c7a2011-11-18 03:28:09 +0000337 context_decl,
Sean Callananbb715f92011-10-29 02:28:18 +0000338 (predicate ? "non-null" : "null"));
339 else
Sean Callanan5a55c7a2011-11-18 03:28:09 +0000340 log->Printf("FindExternalLexicalDecls[%u] on (ASTContext*)%p in a NULL context with %s predicate",
Sean Callananbb715f92011-10-29 02:28:18 +0000341 current_id,
Sean Callanan5a55c7a2011-11-18 03:28:09 +0000342 m_ast_context,
Sean Callananbb715f92011-10-29 02:28:18 +0000343 (predicate ? "non-null" : "null"));
344 }
345
346 Decl *original_decl = NULL;
347 ASTContext *original_ctx = NULL;
348
349 if (!m_ast_importer->ResolveDeclOrigin(context_decl, &original_decl, &original_ctx))
350 return ELR_Failure;
351
352 if (log)
353 {
Sean Callanan6e22e8b2012-01-13 22:05:55 +0000354 log->Printf(" FELD[%u] Original decl (Decl*)%p:", current_id, original_decl);
Sean Callananbb715f92011-10-29 02:28:18 +0000355 ASTDumper(original_decl).ToLog(log, " ");
356 }
357
358 if (TagDecl *original_tag_decl = dyn_cast<TagDecl>(original_decl))
359 {
360 ExternalASTSource *external_source = original_ctx->getExternalSource();
361
362 if (external_source)
363 external_source->CompleteType (original_tag_decl);
364 }
365
Sean Callananb2027ec2011-12-08 23:45:45 +0000366 const DeclContext *original_decl_context = dyn_cast<DeclContext>(original_decl);
Sean Callananbb715f92011-10-29 02:28:18 +0000367
368 if (!original_decl_context)
369 return ELR_Failure;
370
371 for (TagDecl::decl_iterator iter = original_decl_context->decls_begin();
372 iter != original_decl_context->decls_end();
373 ++iter)
374 {
375 Decl *decl = *iter;
376
377 if (!predicate || predicate(decl->getKind()))
378 {
379 if (log)
380 {
381 ASTDumper ast_dumper(decl);
382 if (const NamedDecl *context_named_decl = dyn_cast<NamedDecl>(context_decl))
383 log->Printf(" FELD[%d] Adding [to %s] lexical decl %s", current_id, context_named_decl->getNameAsString().c_str(), ast_dumper.GetCString());
384 else
385 log->Printf(" FELD[%d] Adding lexical decl %s", current_id, ast_dumper.GetCString());
386 }
387
Sean Callanan4938bd62011-11-16 18:20:47 +0000388 Decl *copied_decl = m_ast_importer->CopyDecl(m_ast_context, original_ctx, decl);
Sean Callananbb715f92011-10-29 02:28:18 +0000389
390 decls.push_back(copied_decl);
391 }
392 }
393
394 return ELR_AlreadyLoaded;
Chris Lattner24943d22010-06-08 16:52:24 +0000395}
396
Sean Callanan9394b5a2011-10-29 19:50:43 +0000397void
398ClangASTSource::FindExternalVisibleDecls (NameSearchContext &context)
399{
400 assert (m_ast_context);
401
402 const ConstString name(context.m_decl_name.getAsString().c_str());
403
404 lldb::LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS));
405
406 static unsigned int invocation_id = 0;
407 unsigned int current_id = invocation_id++;
408
409 if (log)
410 {
411 if (!context.m_decl_context)
Sean Callanan6e22e8b2012-01-13 22:05:55 +0000412 log->Printf("ClangASTSource::FindExternalVisibleDecls[%u] on (ASTContext*)%p for '%s' in a NULL DeclContext", current_id, m_ast_context, name.GetCString());
Sean Callanan9394b5a2011-10-29 19:50:43 +0000413 else if (const NamedDecl *context_named_decl = dyn_cast<NamedDecl>(context.m_decl_context))
Sean Callanan5a55c7a2011-11-18 03:28:09 +0000414 log->Printf("ClangASTSource::FindExternalVisibleDecls[%u] on (ASTContext*)%p for '%s' in '%s'", current_id, m_ast_context, name.GetCString(), context_named_decl->getNameAsString().c_str());
Sean Callanan9394b5a2011-10-29 19:50:43 +0000415 else
Sean Callanan5a55c7a2011-11-18 03:28:09 +0000416 log->Printf("ClangASTSource::FindExternalVisibleDecls[%u] on (ASTContext*)%p for '%s' in a '%s'", current_id, m_ast_context, name.GetCString(), context.m_decl_context->getDeclKindName());
Sean Callanan9394b5a2011-10-29 19:50:43 +0000417 }
418
419 context.m_namespace_map.reset(new ClangASTImporter::NamespaceMap);
420
421 if (const NamespaceDecl *namespace_context = dyn_cast<NamespaceDecl>(context.m_decl_context))
422 {
423 ClangASTImporter::NamespaceMapSP namespace_map = m_ast_importer->GetNamespaceMap(namespace_context);
424
425 if (log && log->GetVerbose())
426 log->Printf(" CAS::FEVD[%u] Inspecting namespace map %p (%d entries)",
427 current_id,
428 namespace_map.get(),
429 (int)namespace_map->size());
430
431 if (!namespace_map)
432 return;
433
434 for (ClangASTImporter::NamespaceMap::iterator i = namespace_map->begin(), e = namespace_map->end();
435 i != e;
436 ++i)
437 {
438 if (log)
439 log->Printf(" CAS::FEVD[%u] Searching namespace %s in module %s",
440 current_id,
441 i->second.GetNamespaceDecl()->getNameAsString().c_str(),
442 i->first->GetFileSpec().GetFilename().GetCString());
443
444 FindExternalVisibleDecls(context,
445 i->first,
446 i->second,
447 current_id);
448 }
449 }
Sean Callanand3812fa2011-11-15 21:50:18 +0000450 else if (isa<ObjCInterfaceDecl>(context.m_decl_context))
Sean Callanane6ea5fe2011-11-15 02:11:17 +0000451 {
Sean Callanan8f2e3922012-02-04 08:49:35 +0000452 FindObjCPropertyAndIvarDecls(context);
Sean Callanane6ea5fe2011-11-15 02:11:17 +0000453 }
Sean Callanan9394b5a2011-10-29 19:50:43 +0000454 else if (!isa<TranslationUnitDecl>(context.m_decl_context))
455 {
456 // we shouldn't be getting FindExternalVisibleDecls calls for these
457 return;
458 }
459 else
460 {
461 ClangNamespaceDecl namespace_decl;
462
463 if (log)
464 log->Printf(" CAS::FEVD[%u] Searching the root namespace", current_id);
465
466 FindExternalVisibleDecls(context,
467 lldb::ModuleSP(),
468 namespace_decl,
469 current_id);
470 }
471
472 if (!context.m_namespace_map->empty())
473 {
474 if (log && log->GetVerbose())
475 log->Printf(" CAS::FEVD[%u] Registering namespace map %p (%d entries)",
476 current_id,
477 context.m_namespace_map.get(),
478 (int)context.m_namespace_map->size());
479
480 NamespaceDecl *clang_namespace_decl = AddNamespace(context, context.m_namespace_map);
481
482 if (clang_namespace_decl)
483 clang_namespace_decl->setHasExternalVisibleStorage();
484 }
485}
486
487void
488ClangASTSource::FindExternalVisibleDecls (NameSearchContext &context,
489 lldb::ModuleSP module_sp,
490 ClangNamespaceDecl &namespace_decl,
491 unsigned int current_id)
492{
493 assert (m_ast_context);
494
495 lldb::LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS));
496
497 SymbolContextList sc_list;
498
499 const ConstString name(context.m_decl_name.getAsString().c_str());
500
501 const char *name_unique_cstr = name.GetCString();
502
Sean Callanan8f2e3922012-02-04 08:49:35 +0000503 static ConstString id_name("id");
504 static ConstString Class_name("Class");
505
506 if (name == id_name || name == Class_name)
507 return;
508
Sean Callanan9394b5a2011-10-29 19:50:43 +0000509 if (name_unique_cstr == NULL)
510 return;
511
512 // The ClangASTSource is not responsible for finding $-names.
513 if (name_unique_cstr[0] == '$')
514 return;
515
516 if (module_sp && namespace_decl)
517 {
518 ClangNamespaceDecl found_namespace_decl;
519
520 SymbolVendor *symbol_vendor = module_sp->GetSymbolVendor();
521
522 if (symbol_vendor)
523 {
524 SymbolContext null_sc;
525
526 found_namespace_decl = symbol_vendor->FindNamespace(null_sc, name, &namespace_decl);
527
528 if (found_namespace_decl)
529 {
530 context.m_namespace_map->push_back(std::pair<lldb::ModuleSP, ClangNamespaceDecl>(module_sp, found_namespace_decl));
531
532 if (log)
533 log->Printf(" CAS::FEVD[%u] Found namespace %s in module %s",
534 current_id,
535 name.GetCString(),
536 module_sp->GetFileSpec().GetFilename().GetCString());
537 }
538 }
539 }
540 else
541 {
542 ModuleList &images = m_target->GetImages();
543
544 for (uint32_t i = 0, e = images.GetSize();
545 i != e;
546 ++i)
547 {
548 lldb::ModuleSP image = images.GetModuleAtIndex(i);
549
550 if (!image)
551 continue;
552
553 ClangNamespaceDecl found_namespace_decl;
554
555 SymbolVendor *symbol_vendor = image->GetSymbolVendor();
556
557 if (!symbol_vendor)
558 continue;
559
560 SymbolContext null_sc;
561
562 found_namespace_decl = symbol_vendor->FindNamespace(null_sc, name, &namespace_decl);
563
564 if (found_namespace_decl)
565 {
566 context.m_namespace_map->push_back(std::pair<lldb::ModuleSP, ClangNamespaceDecl>(image, found_namespace_decl));
567
568 if (log)
569 log->Printf(" CAS::FEVD[%u] Found namespace %s in module %s",
570 current_id,
571 name.GetCString(),
572 image->GetFileSpec().GetFilename().GetCString());
573 }
574 }
575 }
576
Sean Callanan9394b5a2011-10-29 19:50:43 +0000577 do
578 {
579 TypeList types;
580 SymbolContext null_sc;
Sean Callanan0f71d192011-12-19 19:38:39 +0000581
Sean Callanan9394b5a2011-10-29 19:50:43 +0000582 if (module_sp && namespace_decl)
583 module_sp->FindTypes(null_sc, name, &namespace_decl, true, 1, types);
Sean Callanan0f71d192011-12-19 19:38:39 +0000584 else
Sean Callanane1301a62011-12-06 03:41:14 +0000585 m_target->GetImages().FindTypes(null_sc, name, true, 1, types);
Sean Callanan9394b5a2011-10-29 19:50:43 +0000586
587 if (types.GetSize())
588 {
589 lldb::TypeSP type_sp = types.GetTypeAtIndex(0);
590
591 if (log)
592 {
593 const char *name_string = type_sp->GetName().GetCString();
594
595 log->Printf(" CAS::FEVD[%u] Matching type found for \"%s\": %s",
596 current_id,
597 name.GetCString(),
598 (name_string ? name_string : "<anonymous>"));
599 }
600
Sean Callanane1301a62011-12-06 03:41:14 +0000601
Sean Callanan9394b5a2011-10-29 19:50:43 +0000602 void *copied_type = GuardedCopyType(m_ast_context, type_sp->GetClangAST(), type_sp->GetClangFullType());
Sean Callanane1301a62011-12-06 03:41:14 +0000603
Sean Callanandc5fce12011-12-01 21:04:37 +0000604 if (!copied_type)
605 {
606 if (log)
Sean Callanane1301a62011-12-06 03:41:14 +0000607 log->Printf(" CAS::FEVD[%u] - Couldn't export the type for a constant integer result",
608 current_id);
609
Sean Callanandc5fce12011-12-01 21:04:37 +0000610 break;
611 }
612
Sean Callanan9394b5a2011-10-29 19:50:43 +0000613 context.AddTypeDecl(copied_type);
614 }
Sean Callanan673f3db2011-11-30 22:11:59 +0000615
Sean Callanan9394b5a2011-10-29 19:50:43 +0000616 } while(0);
617}
618
Sean Callanan9b714842011-11-09 19:33:21 +0000619void
620ClangASTSource::FindObjCMethodDecls (NameSearchContext &context)
621{
622 lldb::LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS));
623
Sean Callananf2a0a5c2011-11-11 20:37:26 +0000624 static unsigned int invocation_id = 0;
625 unsigned int current_id = invocation_id++;
626
Sean Callanan9b714842011-11-09 19:33:21 +0000627 const DeclarationName &decl_name(context.m_decl_name);
628 const DeclContext *decl_ctx(context.m_decl_context);
629
630 const ObjCInterfaceDecl *interface_decl = dyn_cast<ObjCInterfaceDecl>(decl_ctx);
631
632 if (!interface_decl)
633 return;
634
635 StreamString ss;
Sean Callanane1301a62011-12-06 03:41:14 +0000636
Sean Callanan9b714842011-11-09 19:33:21 +0000637 if (decl_name.isObjCZeroArgSelector())
638 {
639 ss.Printf("%s", decl_name.getAsString().c_str());
640 }
641 else if (decl_name.isObjCOneArgSelector())
642 {
Sean Callanan1d9ffe22011-11-14 18:29:46 +0000643 ss.Printf("%s", decl_name.getAsString().c_str());
Sean Callanan9b714842011-11-09 19:33:21 +0000644 }
645 else
646 {
647 clang::Selector sel = decl_name.getObjCSelector();
648
649 for (unsigned i = 0, e = sel.getNumArgs();
650 i != e;
651 ++i)
652 {
653 llvm::StringRef r = sel.getNameForSlot(i);
654 ss.Printf("%s:", r.str().c_str());
655 }
656 }
657 ss.Flush();
658
Sean Callananf2a0a5c2011-11-11 20:37:26 +0000659 ConstString selector_name(ss.GetData());
660
Sean Callanan9b714842011-11-09 19:33:21 +0000661 if (log)
Sean Callanan5a55c7a2011-11-18 03:28:09 +0000662 log->Printf("ClangASTSource::FindObjCMethodDecls[%d] on (ASTContext*)%p for selector [%s %s]",
663 current_id,
664 m_ast_context,
Sean Callananf2a0a5c2011-11-11 20:37:26 +0000665 interface_decl->getNameAsString().c_str(),
666 selector_name.AsCString());
Sean Callananf2a0a5c2011-11-11 20:37:26 +0000667 SymbolContextList sc_list;
668
669 const bool include_symbols = false;
670 const bool append = false;
671
Sean Callanane0028b82012-01-19 02:17:40 +0000672 std::string interface_name = interface_decl->getNameAsString();
673
674 do
675 {
676 StreamString ms;
677 ms.Printf("-[%s %s]", interface_name.c_str(), selector_name.AsCString());
678 ms.Flush();
679 ConstString instance_method_name(ms.GetData());
680
681 m_target->GetImages().FindFunctions(instance_method_name, lldb::eFunctionNameTypeFull, include_symbols, append, sc_list);
682
683 if (sc_list.GetSize())
684 break;
685
686 ms.Clear();
687 ms.Printf("+[%s %s]", interface_name.c_str(), selector_name.AsCString());
688 ms.Flush();
689 ConstString class_method_name(ms.GetData());
690
691 m_target->GetImages().FindFunctions(class_method_name, lldb::eFunctionNameTypeFull, include_symbols, append, sc_list);
692
693 if (sc_list.GetSize())
694 break;
695
696 // Fall back and check for methods in categories. If we find methods this way, we need to check that they're actually in
697 // categories on the desired class.
698
699 SymbolContextList candidate_sc_list;
700
701 m_target->GetImages().FindFunctions(selector_name, lldb::eFunctionNameTypeSelector, include_symbols, append, candidate_sc_list);
702
703 for (uint32_t ci = 0, ce = candidate_sc_list.GetSize();
704 ci != ce;
705 ++ci)
706 {
707 SymbolContext candidate_sc;
708
709 if (!candidate_sc_list.GetContextAtIndex(ci, candidate_sc))
710 continue;
711
712 if (!candidate_sc.function)
713 continue;
714
715 const char *candidate_name = candidate_sc.function->GetName().AsCString();
716
717 const char *cursor = candidate_name;
718
719 if (*cursor != '+' && *cursor != '-')
720 continue;
721
722 ++cursor;
723
724 if (*cursor != '[')
725 continue;
726
727 ++cursor;
728
729 size_t interface_len = interface_name.length();
730
731 if (strncmp(cursor, interface_name.c_str(), interface_len))
732 continue;
733
734 cursor += interface_len;
735
736 if (*cursor == ' ' || *cursor == '(')
737 sc_list.Append(candidate_sc);
738 }
739 }
740 while (0);
Sean Callananf2a0a5c2011-11-11 20:37:26 +0000741
742 for (uint32_t i = 0, e = sc_list.GetSize();
743 i != e;
744 ++i)
745 {
746 SymbolContext sc;
747
748 if (!sc_list.GetContextAtIndex(i, sc))
749 continue;
750
751 if (!sc.function)
752 continue;
753
754 DeclContext *function_ctx = sc.function->GetClangDeclContext();
755
756 if (!function_ctx)
757 continue;
758
759 ObjCMethodDecl *method_decl = dyn_cast<ObjCMethodDecl>(function_ctx);
760
761 if (!method_decl)
762 continue;
763
764 ObjCInterfaceDecl *found_interface_decl = method_decl->getClassInterface();
765
766 if (!found_interface_decl)
767 continue;
768
769 if (found_interface_decl->getName() == interface_decl->getName())
770 {
Sean Callanan4938bd62011-11-16 18:20:47 +0000771 Decl *copied_decl = m_ast_importer->CopyDecl(m_ast_context, &method_decl->getASTContext(), method_decl);
Sean Callananf2a0a5c2011-11-11 20:37:26 +0000772
773 if (!copied_decl)
774 continue;
775
776 ObjCMethodDecl *copied_method_decl = dyn_cast<ObjCMethodDecl>(copied_decl);
777
778 if (!copied_method_decl)
779 continue;
780
781 if (log)
782 {
783 ASTDumper dumper((Decl*)copied_method_decl);
Sean Callanane1301a62011-12-06 03:41:14 +0000784 log->Printf(" CAS::FOMD[%d] found (in debug info) %s", current_id, dumper.GetCString());
Sean Callananf2a0a5c2011-11-11 20:37:26 +0000785 }
Sean Callanane0028b82012-01-19 02:17:40 +0000786
Sean Callananf2a0a5c2011-11-11 20:37:26 +0000787 context.AddNamedDecl(copied_method_decl);
788 }
789 }
Sean Callanan9b714842011-11-09 19:33:21 +0000790}
791
Sean Callanan8f2e3922012-02-04 08:49:35 +0000792template <class D> class TaggedASTDecl {
793public:
794 TaggedASTDecl() : decl(NULL) { }
795 TaggedASTDecl(D *_decl) : decl(_decl) { }
796 bool IsValid() const { return (decl != NULL); }
797 bool IsInvalid() const { return !IsValid(); }
798 D *operator->() const { return decl; }
799 D *decl;
800};
801
802template <class D2, template <class D> class TD, class D1>
803TD<D2>
804DynCast(TD<D1> source)
805{
806 return TD<D2> (dyn_cast<D2>(source.decl));
807}
808
809template <class D = Decl> class DeclFromParser;
810template <class D = Decl> class DeclFromUser;
811
812template <class D> class DeclFromParser : public TaggedASTDecl<D> {
813public:
814 DeclFromParser() : TaggedASTDecl<D>() { }
815 DeclFromParser(D *_decl) : TaggedASTDecl<D>(_decl) { }
816
817 DeclFromUser<D> GetOrigin(ClangASTImporter *importer);
818};
819
820template <class D> class DeclFromUser : public TaggedASTDecl<D> {
821public:
822 DeclFromUser() : TaggedASTDecl<D>() { }
823 DeclFromUser(D *_decl) : TaggedASTDecl<D>(_decl) { }
824
825 DeclFromParser<D> Import(ClangASTImporter *importer, ASTContext &dest_ctx);
826};
827
828template <class D>
829DeclFromUser<D>
830DeclFromParser<D>::GetOrigin(ClangASTImporter *importer)
831{
832 DeclFromUser <> origin_decl;
833 importer->ResolveDeclOrigin(this->decl, &origin_decl.decl, NULL);
834 if (origin_decl.IsInvalid())
835 return DeclFromUser<D>();
836 return DeclFromUser<D>(dyn_cast<D>(origin_decl.decl));
837}
838
839template <class D>
840DeclFromParser<D>
841DeclFromUser<D>::Import(ClangASTImporter *importer, ASTContext &dest_ctx)
842{
843 DeclFromParser <> parser_generic_decl(importer->CopyDecl(&dest_ctx, &this->decl->getASTContext(), this->decl));
844 if (parser_generic_decl.IsInvalid())
845 return DeclFromParser<D>();
846 return DeclFromParser<D>(dyn_cast<D>(parser_generic_decl.decl));
847}
848
Sean Callanane6ea5fe2011-11-15 02:11:17 +0000849void
Sean Callanan8f2e3922012-02-04 08:49:35 +0000850ClangASTSource::FindObjCPropertyAndIvarDecls (NameSearchContext &context)
Sean Callanane6ea5fe2011-11-15 02:11:17 +0000851{
852 lldb::LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS));
853
854 static unsigned int invocation_id = 0;
855 unsigned int current_id = invocation_id++;
856
Sean Callanan8f2e3922012-02-04 08:49:35 +0000857 DeclFromParser<const ObjCInterfaceDecl> parser_iface_decl(cast<ObjCInterfaceDecl>(context.m_decl_context));
858 DeclFromUser<const ObjCInterfaceDecl> origin_iface_decl(parser_iface_decl.GetOrigin(m_ast_importer));
Sean Callanane6ea5fe2011-11-15 02:11:17 +0000859
Sean Callanan8f2e3922012-02-04 08:49:35 +0000860 if (origin_iface_decl.IsInvalid())
Sean Callanane6ea5fe2011-11-15 02:11:17 +0000861 return;
862
Sean Callanan8f2e3922012-02-04 08:49:35 +0000863 std::string name_str = context.m_decl_name.getAsString();
864 StringRef name(name_str.c_str());
865 IdentifierInfo &name_identifier(origin_iface_decl->getASTContext().Idents.get(name));
Sean Callanane6ea5fe2011-11-15 02:11:17 +0000866
867 if (log)
Sean Callanan8f2e3922012-02-04 08:49:35 +0000868 log->Printf("ClangASTSource::FindObjCPropertyAndIvarDecls[%d] on (ASTContext*)%p for '%s.%s'",
Sean Callanane6ea5fe2011-11-15 02:11:17 +0000869 current_id,
Sean Callanan5a55c7a2011-11-18 03:28:09 +0000870 m_ast_context,
Sean Callanan8f2e3922012-02-04 08:49:35 +0000871 parser_iface_decl->getNameAsString().c_str(),
872 name_str.c_str());
Sean Callanane6ea5fe2011-11-15 02:11:17 +0000873
Sean Callanan8f2e3922012-02-04 08:49:35 +0000874 DeclFromUser<ObjCPropertyDecl> origin_property_decl(origin_iface_decl->FindPropertyDeclaration(&name_identifier));
Sean Callanane6ea5fe2011-11-15 02:11:17 +0000875
Sean Callanan8f2e3922012-02-04 08:49:35 +0000876 if (origin_property_decl.IsValid())
877 {
878 DeclFromParser<ObjCPropertyDecl> parser_property_decl(origin_property_decl.Import(m_ast_importer, *m_ast_context));
879 if (parser_property_decl.IsValid())
880 {
881 if (log)
882 {
883 ASTDumper dumper((Decl*)parser_property_decl.decl);
884 log->Printf(" CAS::FOPD[%d] found %s", current_id, dumper.GetCString());
885 }
886
887 context.AddNamedDecl(parser_property_decl.decl);
888 }
889 }
Sean Callanane6ea5fe2011-11-15 02:11:17 +0000890
Sean Callanan8f2e3922012-02-04 08:49:35 +0000891 DeclFromUser<ObjCIvarDecl> origin_ivar_decl(origin_iface_decl->getIvarDecl(&name_identifier));
Sean Callanane6ea5fe2011-11-15 02:11:17 +0000892
Sean Callanan8f2e3922012-02-04 08:49:35 +0000893 if (origin_ivar_decl.IsValid())
894 {
895 DeclFromParser<ObjCIvarDecl> parser_ivar_decl(origin_ivar_decl.Import(m_ast_importer, *m_ast_context));
896 if (parser_ivar_decl.IsValid())
897 {
898 if (log)
899 {
900 ASTDumper dumper((Decl*)parser_ivar_decl.decl);
901 log->Printf(" CAS::FOPD[%d] found %s", current_id, dumper.GetCString());
902 }
903
904 context.AddNamedDecl(parser_ivar_decl.decl);
905 }
906 }
907}
908
909typedef llvm::DenseMap <const FieldDecl *, uint64_t> FieldOffsetMap;
910typedef llvm::DenseMap <const CXXRecordDecl *, CharUnits> BaseOffsetMap;
911
912template <class D, class O>
913static bool
914ImportOffsetMap (llvm::DenseMap <const D*, O> &destination_map,
915 llvm::DenseMap <const D*, O> &source_map,
916 ClangASTImporter *importer,
917 ASTContext &dest_ctx)
918{
919 typedef llvm::DenseMap <const D*, O> MapType;
Sean Callanane6ea5fe2011-11-15 02:11:17 +0000920
Sean Callanan8f2e3922012-02-04 08:49:35 +0000921 for (typename MapType::iterator fi = source_map.begin(), fe = source_map.end();
922 fi != fe;
923 ++fi)
924 {
925 DeclFromUser <D> user_decl(const_cast<D*>(fi->first));
926 DeclFromParser <D> parser_decl(user_decl.Import(importer, dest_ctx));
927 if (parser_decl.IsInvalid())
928 return false;
929 destination_map.insert(std::pair<const D *, O>(parser_decl.decl, fi->second));
930 }
931
932 return true;
933}
934
935template <bool IsVirtual> bool ExtractBaseOffsets (const ASTRecordLayout &record_layout,
936 DeclFromUser<const CXXRecordDecl> &record,
937 BaseOffsetMap &base_offsets)
938{
939 for (CXXRecordDecl::base_class_const_iterator
940 bi = (IsVirtual ? record->vbases_begin() : record->bases_begin()),
941 be = (IsVirtual ? record->vbases_end() : record->bases_end());
942 bi != be;
943 ++bi)
944 {
945 if (!IsVirtual && bi->isVirtual())
946 continue;
947
948 const clang::Type *origin_base_type = bi->getType().getTypePtr();
949 const clang::RecordType *origin_base_record_type = origin_base_type->getAs<RecordType>();
950
951 if (!origin_base_record_type)
952 return false;
953
954 DeclFromUser <RecordDecl> origin_base_record(origin_base_record_type->getDecl());
955
956 if (origin_base_record.IsInvalid())
957 return false;
958
959 DeclFromUser <CXXRecordDecl> origin_base_cxx_record(DynCast<CXXRecordDecl>(origin_base_record));
960
961 if (origin_base_cxx_record.IsInvalid())
962 return false;
963
964 CharUnits base_offset;
965
966 if (IsVirtual)
967 base_offset = record_layout.getVBaseClassOffset(origin_base_cxx_record.decl);
968 else
969 base_offset = record_layout.getBaseClassOffset(origin_base_cxx_record.decl);
970
971 base_offsets.insert(std::pair<const CXXRecordDecl *, CharUnits>(origin_base_cxx_record.decl, base_offset));
972 }
973
974 return true;
975}
976
977bool
978ClangASTSource::layoutRecordType(const RecordDecl *record,
979 uint64_t &size,
980 uint64_t &alignment,
981 FieldOffsetMap &field_offsets,
982 BaseOffsetMap &base_offsets,
983 BaseOffsetMap &virtual_base_offsets)
984{
985 static unsigned int invocation_id = 0;
986 unsigned int current_id = invocation_id++;
987
988 lldb::LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS));
989
990 if (!record->getNameAsString().compare("PseudoObjectExprBitfields"))
991 fprintf(stderr, "THIS IS THE ONE!");
Sean Callanane6ea5fe2011-11-15 02:11:17 +0000992
993 if (log)
994 {
Sean Callanan8f2e3922012-02-04 08:49:35 +0000995 log->Printf("LayoutRecordType[%u] on (RecordDecl*)%p [name = '%s']",
996 current_id,
997 m_ast_context,
998 record->getNameAsString().c_str());
Sean Callanane6ea5fe2011-11-15 02:11:17 +0000999 }
Sean Callanan8f2e3922012-02-04 08:49:35 +00001000
1001
1002 DeclFromParser <const RecordDecl> parser_record(record);
1003 DeclFromUser <const RecordDecl> origin_record(parser_record.GetOrigin(m_ast_importer));
1004
1005 if (origin_record.IsInvalid())
1006 return false;
1007
1008 FieldOffsetMap origin_field_offsets;
1009 BaseOffsetMap origin_base_offsets;
1010 BaseOffsetMap origin_virtual_base_offsets;
1011
1012 const ASTRecordLayout &record_layout(origin_record->getASTContext().getASTRecordLayout(origin_record.decl));
1013
1014 int field_idx = 0;
1015
1016 for (RecordDecl::field_iterator fi = origin_record->field_begin(), fe = origin_record->field_end();
1017 fi != fe;
1018 ++fi)
1019 {
1020 uint64_t field_offset = record_layout.getFieldOffset(field_idx);
1021
1022 origin_field_offsets.insert(std::pair<const FieldDecl *, uint64_t>(*fi, field_offset));
1023
1024 field_idx++;
1025 }
1026
1027 ASTContext &parser_ast_context(record->getASTContext());
1028
1029 DeclFromUser <const CXXRecordDecl> origin_cxx_record(DynCast<const CXXRecordDecl>(origin_record));
1030
1031 if (origin_cxx_record.IsValid())
1032 {
1033 if (!ExtractBaseOffsets<false>(record_layout, origin_cxx_record, origin_base_offsets) ||
1034 !ExtractBaseOffsets<true>(record_layout, origin_cxx_record, origin_virtual_base_offsets))
1035 return false;
1036 }
1037
1038 if (!ImportOffsetMap(field_offsets, origin_field_offsets, m_ast_importer, parser_ast_context) ||
1039 !ImportOffsetMap(base_offsets, origin_base_offsets, m_ast_importer, parser_ast_context) ||
1040 !ImportOffsetMap(virtual_base_offsets, origin_virtual_base_offsets, m_ast_importer, parser_ast_context))
1041 return false;
1042
1043 size = record_layout.getSize().getQuantity() * m_ast_context->getCharWidth();
1044 alignment = record_layout.getAlignment().getQuantity() * m_ast_context->getCharWidth();
1045
1046 if (log)
1047 {
1048 log->Printf("LRT[%u] returned:", current_id);
1049 log->Printf("LRT[%u] Original = (RecordDecl*)%p", current_id, origin_record.decl);
1050 log->Printf("LRT[%u] Size = %lld", current_id, size);
1051 log->Printf("LRT[%u] Alignment = %lld", current_id, alignment);
1052 log->Printf("LRT[%u] Fields:", current_id);
1053 for (RecordDecl::field_iterator fi = record->field_begin(), fe = record->field_end();
1054 fi != fe;
1055 ++fi)
1056 {
1057 log->Printf("LRT[%u] (FieldDecl*)%p, Name = '%s', Offset = %lld bits",
1058 current_id,
1059 *fi,
1060 fi->getNameAsString().c_str(),
1061 field_offsets[*fi]);
1062 }
1063 DeclFromParser <const CXXRecordDecl> parser_cxx_record = DynCast<const CXXRecordDecl>(parser_record);
1064 if (parser_cxx_record.IsValid())
1065 {
1066 log->Printf("LRT[%u] Bases:", current_id);
1067 for (CXXRecordDecl::base_class_const_iterator bi = parser_cxx_record->bases_begin(), be = parser_cxx_record->bases_end();
1068 bi != be;
1069 ++bi)
1070 {
1071 bool is_virtual = bi->isVirtual();
1072
1073 QualType base_type = bi->getType();
1074 const RecordType *base_record_type = base_type->getAs<RecordType>();
1075 DeclFromParser <RecordDecl> base_record(base_record_type->getDecl());
1076 DeclFromParser <CXXRecordDecl> base_cxx_record = DynCast<CXXRecordDecl>(base_record);
1077
1078 log->Printf("LRT[%u] %s(CXXRecordDecl*)%p, Name = '%s', Offset = %lld chars",
1079 current_id,
1080 (is_virtual ? "Virtual " : ""),
1081 base_cxx_record.decl,
1082 base_cxx_record.decl->getNameAsString().c_str(),
1083 (is_virtual ? virtual_base_offsets[base_cxx_record.decl].getQuantity() :
1084 base_offsets[base_cxx_record.decl].getQuantity()));
1085 }
1086 }
1087 else
1088 {
1089 log->Printf("LRD[%u] Not a CXXRecord, so no bases", current_id);
1090 }
1091 }
1092
1093 return true;
Sean Callanane6ea5fe2011-11-15 02:11:17 +00001094}
1095
Sean Callanan73b520f2011-10-29 01:58:46 +00001096void
1097ClangASTSource::CompleteNamespaceMap (ClangASTImporter::NamespaceMapSP &namespace_map,
1098 const ConstString &name,
1099 ClangASTImporter::NamespaceMapSP &parent_map) const
1100{
1101 static unsigned int invocation_id = 0;
1102 unsigned int current_id = invocation_id++;
1103
1104 lldb::LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS));
1105
1106 if (log)
1107 {
1108 if (parent_map && parent_map->size())
Sean Callanan5a55c7a2011-11-18 03:28:09 +00001109 log->Printf("CompleteNamespaceMap[%u] on (ASTContext*)%p Searching for namespace %s in namespace %s",
Sean Callanan73b520f2011-10-29 01:58:46 +00001110 current_id,
Sean Callanan5a55c7a2011-11-18 03:28:09 +00001111 m_ast_context,
Sean Callanan73b520f2011-10-29 01:58:46 +00001112 name.GetCString(),
1113 parent_map->begin()->second.GetNamespaceDecl()->getDeclName().getAsString().c_str());
1114 else
Sean Callanan5a55c7a2011-11-18 03:28:09 +00001115 log->Printf("CompleteNamespaceMap[%u] on (ASTContext*)%p Searching for namespace %s",
Sean Callanan73b520f2011-10-29 01:58:46 +00001116 current_id,
Sean Callanan5a55c7a2011-11-18 03:28:09 +00001117 m_ast_context,
Sean Callanan73b520f2011-10-29 01:58:46 +00001118 name.GetCString());
1119 }
1120
1121
1122 if (parent_map)
1123 {
1124 for (ClangASTImporter::NamespaceMap::iterator i = parent_map->begin(), e = parent_map->end();
1125 i != e;
1126 ++i)
1127 {
1128 ClangNamespaceDecl found_namespace_decl;
1129
1130 lldb::ModuleSP module_sp = i->first;
1131 ClangNamespaceDecl module_parent_namespace_decl = i->second;
1132
1133 SymbolVendor *symbol_vendor = module_sp->GetSymbolVendor();
1134
1135 if (!symbol_vendor)
1136 continue;
1137
1138 SymbolContext null_sc;
1139
1140 found_namespace_decl = symbol_vendor->FindNamespace(null_sc, name, &module_parent_namespace_decl);
1141
1142 if (!found_namespace_decl)
1143 continue;
1144
1145 namespace_map->push_back(std::pair<lldb::ModuleSP, ClangNamespaceDecl>(module_sp, found_namespace_decl));
1146
1147 if (log)
1148 log->Printf(" CMN[%u] Found namespace %s in module %s",
1149 current_id,
1150 name.GetCString(),
1151 module_sp->GetFileSpec().GetFilename().GetCString());
1152 }
1153 }
1154 else
1155 {
1156 ModuleList &images = m_target->GetImages();
1157 ClangNamespaceDecl null_namespace_decl;
1158
1159 for (uint32_t i = 0, e = images.GetSize();
1160 i != e;
1161 ++i)
1162 {
1163 lldb::ModuleSP image = images.GetModuleAtIndex(i);
1164
1165 if (!image)
1166 continue;
1167
1168 ClangNamespaceDecl found_namespace_decl;
1169
1170 SymbolVendor *symbol_vendor = image->GetSymbolVendor();
1171
1172 if (!symbol_vendor)
1173 continue;
1174
1175 SymbolContext null_sc;
1176
1177 found_namespace_decl = symbol_vendor->FindNamespace(null_sc, name, &null_namespace_decl);
1178
1179 if (!found_namespace_decl)
1180 continue;
1181
1182 namespace_map->push_back(std::pair<lldb::ModuleSP, ClangNamespaceDecl>(image, found_namespace_decl));
1183
1184 if (log)
1185 log->Printf(" CMN[%u] Found namespace %s in module %s",
1186 current_id,
1187 name.GetCString(),
1188 image->GetFileSpec().GetFilename().GetCString());
1189 }
1190 }
1191}
1192
Sean Callananbb715f92011-10-29 02:28:18 +00001193NamespaceDecl *
1194ClangASTSource::AddNamespace (NameSearchContext &context, ClangASTImporter::NamespaceMapSP &namespace_decls)
1195{
Greg Clayton13d24fb2012-01-29 20:56:30 +00001196 if (!namespace_decls)
Sean Callananbb715f92011-10-29 02:28:18 +00001197 return NULL;
1198
1199 lldb::LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS));
1200
1201 const ClangNamespaceDecl &namespace_decl = namespace_decls->begin()->second;
1202
Sean Callanan4938bd62011-11-16 18:20:47 +00001203 Decl *copied_decl = m_ast_importer->CopyDecl(m_ast_context, namespace_decl.GetASTContext(), namespace_decl.GetNamespaceDecl());
Sean Callananbb715f92011-10-29 02:28:18 +00001204
1205 NamespaceDecl *copied_namespace_decl = dyn_cast<NamespaceDecl>(copied_decl);
1206
1207 m_ast_importer->RegisterNamespaceMap(copied_namespace_decl, namespace_decls);
1208
1209 return dyn_cast<NamespaceDecl>(copied_decl);
1210}
1211
Sean Callanan9394b5a2011-10-29 19:50:43 +00001212void *
1213ClangASTSource::GuardedCopyType (ASTContext *dest_context,
1214 ASTContext *source_context,
1215 void *clang_type)
1216{
1217 SetImportInProgress(true);
1218
Sean Callanan4938bd62011-11-16 18:20:47 +00001219 QualType ret_qual_type = m_ast_importer->CopyType (m_ast_context, source_context, QualType::getFromOpaquePtr(clang_type));
Sean Callanan9394b5a2011-10-29 19:50:43 +00001220
1221 void *ret = ret_qual_type.getAsOpaquePtr();
1222
1223 SetImportInProgress(false);
1224
1225 return ret;
1226}
1227
Greg Claytonb01000f2011-01-17 03:46:26 +00001228clang::NamedDecl *
1229NameSearchContext::AddVarDecl(void *type)
1230{
Greg Clayton8de27c72010-10-15 22:48:33 +00001231 IdentifierInfo *ii = m_decl_name.getAsIdentifierInfo();
Sean Callanan1ddd9fe2010-11-30 00:27:43 +00001232
1233 assert (type && "Type for variable must be non-NULL!");
Sean Callanancc074622010-09-14 21:59:34 +00001234
Sean Callananf76afff2011-10-28 23:38:38 +00001235 clang::NamedDecl *Decl = VarDecl::Create(*m_ast_source.m_ast_context,
Greg Clayton8de27c72010-10-15 22:48:33 +00001236 const_cast<DeclContext*>(m_decl_context),
Chris Lattner24943d22010-06-08 16:52:24 +00001237 SourceLocation(),
Sean Callanan279584c2011-03-15 00:17:19 +00001238 SourceLocation(),
Sean Callanancc074622010-09-14 21:59:34 +00001239 ii,
Chris Lattner24943d22010-06-08 16:52:24 +00001240 QualType::getFromOpaquePtr(type),
1241 0,
Sean Callanan47a5c4c2010-09-23 03:01:22 +00001242 SC_Static,
1243 SC_Static);
Greg Clayton8de27c72010-10-15 22:48:33 +00001244 m_decls.push_back(Decl);
Chris Lattner24943d22010-06-08 16:52:24 +00001245
1246 return Decl;
1247}
Sean Callanan8f0dc342010-06-22 23:46:24 +00001248
Greg Claytonb01000f2011-01-17 03:46:26 +00001249clang::NamedDecl *
1250NameSearchContext::AddFunDecl (void *type)
1251{
Sean Callananf76afff2011-10-28 23:38:38 +00001252 clang::FunctionDecl *func_decl = FunctionDecl::Create (*m_ast_source.m_ast_context,
Greg Clayton8de27c72010-10-15 22:48:33 +00001253 const_cast<DeclContext*>(m_decl_context),
1254 SourceLocation(),
Sean Callanan279584c2011-03-15 00:17:19 +00001255 SourceLocation(),
Greg Clayton8de27c72010-10-15 22:48:33 +00001256 m_decl_name.getAsIdentifierInfo(),
1257 QualType::getFromOpaquePtr(type),
1258 NULL,
1259 SC_Static,
1260 SC_Static,
1261 false,
1262 true);
Sean Callanan8f0dc342010-06-22 23:46:24 +00001263
Sean Callananb291abe2010-08-12 23:45:38 +00001264 // We have to do more than just synthesize the FunctionDecl. We have to
1265 // synthesize ParmVarDecls for all of the FunctionDecl's arguments. To do
1266 // this, we raid the function's FunctionProtoType for types.
1267
Greg Clayton8de27c72010-10-15 22:48:33 +00001268 QualType qual_type (QualType::getFromOpaquePtr(type));
Sean Callanan21f2e192011-12-14 01:13:04 +00001269 const FunctionProtoType *func_proto_type = qual_type.getTypePtr()->getAs<FunctionProtoType>();
Sean Callanan8f0dc342010-06-22 23:46:24 +00001270
Greg Clayton8de27c72010-10-15 22:48:33 +00001271 if (func_proto_type)
Sean Callanan3c821cc2010-06-23 18:58:10 +00001272 {
Greg Clayton8de27c72010-10-15 22:48:33 +00001273 unsigned NumArgs = func_proto_type->getNumArgs();
Sean Callanan8f0dc342010-06-22 23:46:24 +00001274 unsigned ArgIndex;
1275
Sean Callananc1535182011-10-07 23:18:13 +00001276 SmallVector<ParmVarDecl *, 5> parm_var_decls;
1277
Sean Callanan8f0dc342010-06-22 23:46:24 +00001278 for (ArgIndex = 0; ArgIndex < NumArgs; ++ArgIndex)
1279 {
Greg Clayton8de27c72010-10-15 22:48:33 +00001280 QualType arg_qual_type (func_proto_type->getArgType(ArgIndex));
Sean Callanan8f0dc342010-06-22 23:46:24 +00001281
Sean Callananf76afff2011-10-28 23:38:38 +00001282 parm_var_decls.push_back(ParmVarDecl::Create (*m_ast_source.m_ast_context,
Sean Callananc1535182011-10-07 23:18:13 +00001283 const_cast<DeclContext*>(m_decl_context),
1284 SourceLocation(),
1285 SourceLocation(),
1286 NULL,
1287 arg_qual_type,
1288 NULL,
1289 SC_Static,
1290 SC_Static,
1291 NULL));
Sean Callanan8f0dc342010-06-22 23:46:24 +00001292 }
1293
Sean Callananc1535182011-10-07 23:18:13 +00001294 func_decl->setParams(ArrayRef<ParmVarDecl*>(parm_var_decls));
Sean Callanan8f0dc342010-06-22 23:46:24 +00001295 }
Sean Callanandc5fce12011-12-01 21:04:37 +00001296 else
1297 {
1298 lldb::LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS));
1299
1300 log->Printf("Function type wasn't a FunctionProtoType");
1301 }
Sean Callanan8f0dc342010-06-22 23:46:24 +00001302
Greg Clayton8de27c72010-10-15 22:48:33 +00001303 m_decls.push_back(func_decl);
Sean Callanan8f0dc342010-06-22 23:46:24 +00001304
Greg Clayton8de27c72010-10-15 22:48:33 +00001305 return func_decl;
Sean Callanan8f0dc342010-06-22 23:46:24 +00001306}
Sean Callanan0fc73582010-07-27 00:55:47 +00001307
Greg Claytonb01000f2011-01-17 03:46:26 +00001308clang::NamedDecl *
1309NameSearchContext::AddGenericFunDecl()
Sean Callanan0fc73582010-07-27 00:55:47 +00001310{
Sean Callananad293092011-01-18 23:32:05 +00001311 FunctionProtoType::ExtProtoInfo proto_info;
1312
1313 proto_info.Variadic = true;
1314
Sean Callananf76afff2011-10-28 23:38:38 +00001315 QualType generic_function_type(m_ast_source.m_ast_context->getFunctionType (m_ast_source.m_ast_context->UnknownAnyTy, // result
1316 NULL, // argument types
1317 0, // number of arguments
1318 proto_info));
Greg Clayton8de27c72010-10-15 22:48:33 +00001319
Sean Callanan0fc73582010-07-27 00:55:47 +00001320 return AddFunDecl(generic_function_type.getAsOpaquePtr());
1321}
Sean Callanan93a4b1a2010-08-04 01:02:13 +00001322
Greg Claytonb01000f2011-01-17 03:46:26 +00001323clang::NamedDecl *
1324NameSearchContext::AddTypeDecl(void *type)
Sean Callanan93a4b1a2010-08-04 01:02:13 +00001325{
Greg Claytona1aaaff2011-01-23 00:34:52 +00001326 if (type)
1327 {
1328 QualType qual_type = QualType::getFromOpaquePtr(type);
Sean Callanan93a4b1a2010-08-04 01:02:13 +00001329
Sean Callanan21f2e192011-12-14 01:13:04 +00001330 if (const TagType *tag_type = qual_type->getAs<TagType>())
Greg Claytona1aaaff2011-01-23 00:34:52 +00001331 {
1332 TagDecl *tag_decl = tag_type->getDecl();
1333
1334 m_decls.push_back(tag_decl);
1335
1336 return tag_decl;
1337 }
Sean Callanan21f2e192011-12-14 01:13:04 +00001338 else if (const ObjCObjectType *objc_object_type = qual_type->getAs<ObjCObjectType>())
Greg Claytona1aaaff2011-01-23 00:34:52 +00001339 {
1340 ObjCInterfaceDecl *interface_decl = objc_object_type->getInterface();
1341
1342 m_decls.push_back((NamedDecl*)interface_decl);
1343
1344 return (NamedDecl*)interface_decl;
1345 }
Sean Callanan93a4b1a2010-08-04 01:02:13 +00001346 }
Greg Claytona1aaaff2011-01-23 00:34:52 +00001347 return NULL;
Sean Callanan93a4b1a2010-08-04 01:02:13 +00001348}
Greg Claytone6d72ca2011-06-25 00:44:06 +00001349
1350void
1351NameSearchContext::AddLookupResult (clang::DeclContextLookupConstResult result)
1352{
1353 for (clang::NamedDecl * const *decl_iterator = result.first;
1354 decl_iterator != result.second;
1355 ++decl_iterator)
1356 m_decls.push_back (*decl_iterator);
1357}
1358
1359void
1360NameSearchContext::AddNamedDecl (clang::NamedDecl *decl)
1361{
1362 m_decls.push_back (decl);
1363}