]> CyberLeo.Net >> Repos - FreeBSD/releng/10.0.git/blob - contrib/llvm/tools/lldb/source/Expression/ClangASTSource.cpp
- Copy stable/10 (r259064) to releng/10.0 as part of the
[FreeBSD/releng/10.0.git] / contrib / llvm / tools / lldb / source / Expression / ClangASTSource.cpp
1 //===-- 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
10
11 #include "clang/AST/ASTContext.h"
12 #include "clang/AST/RecordLayout.h"
13 #include "lldb/Core/Log.h"
14 #include "lldb/Core/Module.h"
15 #include "lldb/Core/ModuleList.h"
16 #include "lldb/Expression/ASTDumper.h"
17 #include "lldb/Expression/ClangASTSource.h"
18 #include "lldb/Expression/ClangExpression.h"
19 #include "lldb/Symbol/ClangNamespaceDecl.h"
20 #include "lldb/Symbol/Function.h"
21 #include "lldb/Symbol/SymbolVendor.h"
22 #include "lldb/Target/ObjCLanguageRuntime.h"
23 #include "lldb/Target/Target.h"
24
25 using namespace clang;
26 using namespace lldb_private;
27
28 ClangASTSource::~ClangASTSource() 
29 {
30     m_ast_importer->ForgetDestination(m_ast_context);
31     
32     // We are in the process of destruction, don't create clang ast context on demand
33     // by passing false to Target::GetScratchClangASTContext(create_on_demand).
34     ClangASTContext *scratch_clang_ast_context = m_target->GetScratchClangASTContext(false);
35     
36     if (!scratch_clang_ast_context)
37         return;
38     
39     clang::ASTContext *scratch_ast_context = scratch_clang_ast_context->getASTContext();
40     
41     if (!scratch_ast_context)
42         return;
43     
44     if (m_ast_context != scratch_ast_context)
45         m_ast_importer->ForgetSource(scratch_ast_context, m_ast_context);
46 }
47
48 void
49 ClangASTSource::StartTranslationUnit(ASTConsumer *Consumer) 
50 {
51     if (!m_ast_context)
52         return;
53     
54     m_ast_context->getTranslationUnitDecl()->setHasExternalVisibleStorage();
55     m_ast_context->getTranslationUnitDecl()->setHasExternalLexicalStorage();
56 }
57
58 // The core lookup interface.
59 bool
60 ClangASTSource::FindExternalVisibleDeclsByName
61 (
62     const DeclContext *decl_ctx, 
63     DeclarationName clang_decl_name
64
65 {
66     if (!m_ast_context)
67     {
68         SetNoExternalVisibleDeclsForName(decl_ctx, clang_decl_name);
69         return false;
70     }
71     
72     if (GetImportInProgress())
73     {
74         SetNoExternalVisibleDeclsForName(decl_ctx, clang_decl_name);
75         return false;
76     }
77     
78     std::string decl_name (clang_decl_name.getAsString());
79
80 //    if (m_decl_map.DoingASTImport ())
81 //      return DeclContext::lookup_result();
82 //        
83     switch (clang_decl_name.getNameKind()) {
84     // Normal identifiers.
85     case DeclarationName::Identifier:
86         {
87             clang::IdentifierInfo *identifier_info = clang_decl_name.getAsIdentifierInfo();
88         
89             if (!identifier_info ||
90                 identifier_info->getBuiltinID() != 0)
91             {
92                 SetNoExternalVisibleDeclsForName(decl_ctx, clang_decl_name);
93                 return false;
94             }
95         }
96         break;
97             
98     // Operator names.  Not important for now.
99     case DeclarationName::CXXOperatorName:
100     case DeclarationName::CXXLiteralOperatorName:
101       SetNoExternalVisibleDeclsForName(decl_ctx, clang_decl_name);
102       return false;
103             
104     // Using directives found in this context.
105     // Tell Sema we didn't find any or we'll end up getting asked a *lot*.
106     case DeclarationName::CXXUsingDirective:
107       SetNoExternalVisibleDeclsForName(decl_ctx, clang_decl_name);
108       return false;
109             
110     case DeclarationName::ObjCZeroArgSelector:
111     case DeclarationName::ObjCOneArgSelector:
112     case DeclarationName::ObjCMultiArgSelector:
113     {
114       llvm::SmallVector<NamedDecl*, 1> method_decls;    
115
116       NameSearchContext method_search_context (*this, method_decls, clang_decl_name, decl_ctx);
117      
118       FindObjCMethodDecls(method_search_context);
119
120       SetExternalVisibleDeclsForName (decl_ctx, clang_decl_name, method_decls);
121       return (method_decls.size() > 0);
122     }
123     // These aren't possible in the global context.
124     case DeclarationName::CXXConstructorName:
125     case DeclarationName::CXXDestructorName:
126     case DeclarationName::CXXConversionFunctionName:
127       SetNoExternalVisibleDeclsForName(decl_ctx, clang_decl_name);
128       return false;
129     }
130
131
132     if (!GetLookupsEnabled())
133     {
134         // Wait until we see a '$' at the start of a name before we start doing 
135         // any lookups so we can avoid lookup up all of the builtin types.
136         if (!decl_name.empty() && decl_name[0] == '$')
137         {
138             SetLookupsEnabled (true);
139         }
140         else
141         {               
142             SetNoExternalVisibleDeclsForName(decl_ctx, clang_decl_name);
143             return false;
144         }
145     }
146
147     ConstString const_decl_name(decl_name.c_str());
148     
149     const char *uniqued_const_decl_name = const_decl_name.GetCString();
150     if (m_active_lookups.find (uniqued_const_decl_name) != m_active_lookups.end())
151     {
152         // We are currently looking up this name...
153         SetNoExternalVisibleDeclsForName(decl_ctx, clang_decl_name);
154         return false;
155     }
156     m_active_lookups.insert(uniqued_const_decl_name);
157 //  static uint32_t g_depth = 0;
158 //  ++g_depth;
159 //  printf("[%5u] FindExternalVisibleDeclsByName() \"%s\"\n", g_depth, uniqued_const_decl_name);
160     llvm::SmallVector<NamedDecl*, 4> name_decls;    
161     NameSearchContext name_search_context(*this, name_decls, clang_decl_name, decl_ctx);
162     FindExternalVisibleDecls(name_search_context);
163     SetExternalVisibleDeclsForName (decl_ctx, clang_decl_name, name_decls);
164 //  --g_depth;
165     m_active_lookups.erase (uniqued_const_decl_name);
166     return (name_decls.size() != 0);
167 }
168
169 void
170 ClangASTSource::CompleteType (TagDecl *tag_decl)
171 {    
172     Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS));
173     
174     static unsigned int invocation_id = 0;
175     unsigned int current_id = invocation_id++;
176     
177     if (log)
178     {
179         log->Printf("    CompleteTagDecl[%u] on (ASTContext*)%p Completing (TagDecl*)%p named %s", 
180                     current_id, 
181                     m_ast_context, 
182                     tag_decl,
183                     tag_decl->getName().str().c_str());
184         
185         log->Printf("      CTD[%u] Before:", current_id);
186         ASTDumper dumper((Decl*)tag_decl);
187         dumper.ToLog(log, "      [CTD] ");
188     }
189     
190     if (!m_ast_importer->CompleteTagDecl (tag_decl))
191     {
192         // We couldn't complete the type.  Maybe there's a definition
193         // somewhere else that can be completed.
194         
195         if (log)
196             log->Printf("      CTD[%u] Type could not be completed in the module in which it was first found.", current_id);
197         
198         bool found = false;
199
200         DeclContext *decl_ctx = tag_decl->getDeclContext();
201                 
202         if (const NamespaceDecl *namespace_context = dyn_cast<NamespaceDecl>(decl_ctx))
203         {
204             ClangASTImporter::NamespaceMapSP namespace_map = m_ast_importer->GetNamespaceMap(namespace_context);
205             
206             if (log && log->GetVerbose())
207                 log->Printf("      CTD[%u] Inspecting namespace map %p (%d entries)", 
208                             current_id, 
209                             namespace_map.get(), 
210                             (int)namespace_map->size());
211             
212             if (!namespace_map)
213                 return;
214             
215             for (ClangASTImporter::NamespaceMap::iterator i = namespace_map->begin(), e = namespace_map->end();
216                  i != e && !found;
217                  ++i)
218             {
219                 if (log)
220                     log->Printf("      CTD[%u] Searching namespace %s in module %s",
221                                 current_id,
222                                 i->second.GetNamespaceDecl()->getNameAsString().c_str(),
223                                 i->first->GetFileSpec().GetFilename().GetCString());
224                 
225                 TypeList types;
226                 
227                 SymbolContext null_sc;
228                 ConstString name(tag_decl->getName().str().c_str());
229                 
230                 i->first->FindTypesInNamespace(null_sc, name, &i->second, UINT32_MAX, types);
231                 
232                 for (uint32_t ti = 0, te = types.GetSize();
233                      ti != te && !found;
234                      ++ti)
235                 {
236                     lldb::TypeSP type = types.GetTypeAtIndex(ti);
237                     
238                     if (!type)
239                         continue;
240                     
241                     ClangASTType clang_type (type->GetClangFullType());
242                     
243                     if (!clang_type)
244                         continue;
245                     
246                     const TagType *tag_type = clang_type.GetQualType()->getAs<TagType>();
247                     
248                     if (!tag_type)
249                         continue;
250                     
251                     TagDecl *candidate_tag_decl = const_cast<TagDecl*>(tag_type->getDecl());
252                     
253                     if (m_ast_importer->CompleteTagDeclWithOrigin (tag_decl, candidate_tag_decl))
254                         found = true;
255                 }
256             }
257         }
258         else 
259         {
260             TypeList types;
261             
262             SymbolContext null_sc;
263             ConstString name(tag_decl->getName().str().c_str());
264             ClangNamespaceDecl namespace_decl;
265             
266             const ModuleList &module_list = m_target->GetImages();
267
268             bool exact_match = false;
269             module_list.FindTypes (null_sc, name, exact_match, UINT32_MAX, types);
270             
271             for (uint32_t ti = 0, te = types.GetSize();
272                  ti != te && !found;
273                  ++ti)
274             {
275                 lldb::TypeSP type = types.GetTypeAtIndex(ti);
276                 
277                 if (!type)
278                     continue;
279                 
280                 ClangASTType clang_type (type->GetClangFullType());
281                 
282                 if (!clang_type)
283                     continue;
284                 
285                 const TagType *tag_type = clang_type.GetQualType()->getAs<TagType>();
286                 
287                 if (!tag_type)
288                     continue;
289                 
290                 TagDecl *candidate_tag_decl = const_cast<TagDecl*>(tag_type->getDecl());
291                 
292                 if (m_ast_importer->CompleteTagDeclWithOrigin (tag_decl, candidate_tag_decl))
293                     found = true;
294             }
295         }
296     }
297     
298     if (log)
299     {
300         log->Printf("      [CTD] After:");
301         ASTDumper dumper((Decl*)tag_decl);
302         dumper.ToLog(log, "      [CTD] ");
303     }
304 }
305
306 void
307 ClangASTSource::CompleteType (clang::ObjCInterfaceDecl *interface_decl)
308 {    
309     Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS));
310     
311     if (log)
312     {
313         log->Printf("    [CompleteObjCInterfaceDecl] on (ASTContext*)%p Completing an ObjCInterfaceDecl named %s", m_ast_context, interface_decl->getName().str().c_str());
314         log->Printf("      [COID] Before:");
315         ASTDumper dumper((Decl*)interface_decl);
316         dumper.ToLog(log, "      [COID] ");    
317     }
318     
319     m_ast_importer->CompleteObjCInterfaceDecl (interface_decl);
320     
321     if (log)
322     {
323         log->Printf("      [COID] After:");
324         ASTDumper dumper((Decl*)interface_decl);
325         dumper.ToLog(log, "      [COID] ");    
326     }
327 }
328
329 clang::ObjCInterfaceDecl *
330 ClangASTSource::GetCompleteObjCInterface (clang::ObjCInterfaceDecl *interface_decl)
331 {
332     lldb::ProcessSP process(m_target->GetProcessSP());
333     
334     if (!process)
335         return NULL;
336     
337     ObjCLanguageRuntime *language_runtime(process->GetObjCLanguageRuntime());
338     
339     if (!language_runtime)
340         return NULL;
341         
342     ConstString class_name(interface_decl->getNameAsString().c_str());
343     
344     lldb::TypeSP complete_type_sp(language_runtime->LookupInCompleteClassCache(class_name));
345     
346     if (!complete_type_sp)
347         return NULL;
348     
349     TypeFromUser complete_type = TypeFromUser(complete_type_sp->GetClangFullType());
350     lldb::clang_type_t complete_opaque_type = complete_type.GetOpaqueQualType();
351     
352     if (!complete_opaque_type)
353         return NULL;
354     
355     const clang::Type *complete_clang_type = QualType::getFromOpaquePtr(complete_opaque_type).getTypePtr();
356     const ObjCInterfaceType *complete_interface_type = dyn_cast<ObjCInterfaceType>(complete_clang_type);
357     
358     if (!complete_interface_type)
359         return NULL;
360     
361     ObjCInterfaceDecl *complete_iface_decl(complete_interface_type->getDecl());
362     
363     return complete_iface_decl;
364 }
365
366 clang::ExternalLoadResult
367 ClangASTSource::FindExternalLexicalDecls (const DeclContext *decl_context,
368                                           bool (*predicate)(Decl::Kind),
369                                           llvm::SmallVectorImpl<Decl*> &decls)
370 {
371     ClangASTMetrics::RegisterLexicalQuery();
372
373     Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS));
374     
375     const Decl *context_decl = dyn_cast<Decl>(decl_context);
376     
377     if (!context_decl)
378         return ELR_Failure;
379     
380     static unsigned int invocation_id = 0;
381     unsigned int current_id = invocation_id++;
382     
383     if (log)
384     {
385         if (const NamedDecl *context_named_decl = dyn_cast<NamedDecl>(context_decl))
386             log->Printf("FindExternalLexicalDecls[%u] on (ASTContext*)%p in '%s' (%sDecl*)%p with %s predicate",
387                         current_id,
388                         m_ast_context,
389                         context_named_decl->getNameAsString().c_str(),
390                         context_decl->getDeclKindName(),
391                         context_decl,
392                         (predicate ? "non-null" : "null"));
393         else if(context_decl)
394             log->Printf("FindExternalLexicalDecls[%u] on (ASTContext*)%p in (%sDecl*)%p with %s predicate",
395                         current_id,
396                         m_ast_context,
397                         context_decl->getDeclKindName(), 
398                         context_decl,
399                         (predicate ? "non-null" : "null"));
400         else
401             log->Printf("FindExternalLexicalDecls[%u] on (ASTContext*)%p in a NULL context with %s predicate",
402                         current_id,
403                         m_ast_context,
404                         (predicate ? "non-null" : "null"));
405     }
406     
407     Decl *original_decl = NULL;
408     ASTContext *original_ctx = NULL;
409     
410     if (!m_ast_importer->ResolveDeclOrigin(context_decl, &original_decl, &original_ctx))
411         return ELR_Failure;
412     
413     if (log)
414     {       
415         log->Printf("  FELD[%u] Original decl (ASTContext*)%p (Decl*)%p:", current_id, original_ctx, original_decl);
416         ASTDumper(original_decl).ToLog(log, "    ");
417     }
418     
419     if (ObjCInterfaceDecl *original_iface_decl = dyn_cast<ObjCInterfaceDecl>(original_decl))
420     {
421         ObjCInterfaceDecl *complete_iface_decl = GetCompleteObjCInterface(original_iface_decl);
422         
423         if (complete_iface_decl && (complete_iface_decl != original_iface_decl))
424         {
425             original_decl = complete_iface_decl;
426             original_ctx = &complete_iface_decl->getASTContext();
427             
428             m_ast_importer->SetDeclOrigin(context_decl, original_iface_decl);
429         }
430     }
431     
432     if (TagDecl *original_tag_decl = dyn_cast<TagDecl>(original_decl))
433     {
434         ExternalASTSource *external_source = original_ctx->getExternalSource();
435         
436         if (external_source)
437             external_source->CompleteType (original_tag_decl);
438     }
439     
440     const DeclContext *original_decl_context = dyn_cast<DeclContext>(original_decl);
441     
442     if (!original_decl_context)
443         return ELR_Failure;
444     
445     for (TagDecl::decl_iterator iter = original_decl_context->decls_begin();
446          iter != original_decl_context->decls_end();
447          ++iter)
448     {
449         Decl *decl = *iter;
450         
451         if (!predicate || predicate(decl->getKind()))
452         {
453             if (log)
454             {
455                 ASTDumper ast_dumper(decl);
456                 if (const NamedDecl *context_named_decl = dyn_cast<NamedDecl>(context_decl))
457                     log->Printf("  FELD[%d] Adding [to %sDecl %s] lexical %sDecl %s", current_id, context_named_decl->getDeclKindName(), context_named_decl->getNameAsString().c_str(), decl->getDeclKindName(), ast_dumper.GetCString());
458                 else
459                     log->Printf("  FELD[%d] Adding lexical %sDecl %s", current_id, decl->getDeclKindName(), ast_dumper.GetCString());
460             }
461             
462             Decl *copied_decl = m_ast_importer->CopyDecl(m_ast_context, original_ctx, decl);
463             
464             if (!copied_decl)
465                 continue;
466             
467             if (FieldDecl *copied_field = dyn_cast<FieldDecl>(copied_decl))
468             {
469                 QualType copied_field_type = copied_field->getType();
470                 
471                 m_ast_importer->RequireCompleteType(copied_field_type);
472             }
473             
474             decls.push_back(copied_decl);
475             
476             DeclContext *decl_context_non_const = const_cast<DeclContext *>(decl_context);
477             
478             if (copied_decl->getDeclContext() != decl_context)
479             {
480                 if (copied_decl->getDeclContext()->containsDecl(copied_decl))
481                     copied_decl->getDeclContext()->removeDecl(copied_decl);
482                 copied_decl->setDeclContext(decl_context_non_const);
483             }
484             
485             if (!decl_context_non_const->containsDecl(copied_decl))
486                 decl_context_non_const->addDeclInternal(copied_decl);
487         }
488     }
489     
490     return ELR_AlreadyLoaded;
491 }
492
493 void
494 ClangASTSource::FindExternalVisibleDecls (NameSearchContext &context)
495 {
496     assert (m_ast_context);
497     
498     ClangASTMetrics::RegisterVisibleQuery();
499     
500     const ConstString name(context.m_decl_name.getAsString().c_str());
501     
502     Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS));
503     
504     static unsigned int invocation_id = 0;
505     unsigned int current_id = invocation_id++;
506     
507     if (log)
508     {
509         if (!context.m_decl_context)
510             log->Printf("ClangASTSource::FindExternalVisibleDecls[%u] on (ASTContext*)%p for '%s' in a NULL DeclContext", current_id, m_ast_context, name.GetCString());
511         else if (const NamedDecl *context_named_decl = dyn_cast<NamedDecl>(context.m_decl_context))
512             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());
513         else
514             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());
515     }
516     
517     context.m_namespace_map.reset(new ClangASTImporter::NamespaceMap);
518     
519     if (const NamespaceDecl *namespace_context = dyn_cast<NamespaceDecl>(context.m_decl_context))
520     {
521         ClangASTImporter::NamespaceMapSP namespace_map = m_ast_importer->GetNamespaceMap(namespace_context);
522         
523         if (log && log->GetVerbose())
524             log->Printf("  CAS::FEVD[%u] Inspecting namespace map %p (%d entries)", 
525                         current_id, 
526                         namespace_map.get(), 
527                         (int)namespace_map->size());
528         
529         if (!namespace_map)
530             return;
531         
532         for (ClangASTImporter::NamespaceMap::iterator i = namespace_map->begin(), e = namespace_map->end();
533              i != e;
534              ++i)
535         {
536             if (log)
537                 log->Printf("  CAS::FEVD[%u] Searching namespace %s in module %s",
538                             current_id,
539                             i->second.GetNamespaceDecl()->getNameAsString().c_str(),
540                             i->first->GetFileSpec().GetFilename().GetCString());
541             
542             FindExternalVisibleDecls(context,
543                                      i->first,
544                                      i->second,
545                                      current_id);
546         }
547     }
548     else if (isa<ObjCInterfaceDecl>(context.m_decl_context))
549     {
550         FindObjCPropertyAndIvarDecls(context);
551     }
552     else if (!isa<TranslationUnitDecl>(context.m_decl_context))
553     {
554         // we shouldn't be getting FindExternalVisibleDecls calls for these
555         return;
556     }
557     else
558     {
559         ClangNamespaceDecl namespace_decl;
560         
561         if (log)
562             log->Printf("  CAS::FEVD[%u] Searching the root namespace", current_id);
563         
564         FindExternalVisibleDecls(context,
565                                  lldb::ModuleSP(),
566                                  namespace_decl,
567                                  current_id);
568     }
569     
570     if (!context.m_namespace_map->empty())
571     {
572         if (log && log->GetVerbose())
573             log->Printf("  CAS::FEVD[%u] Registering namespace map %p (%d entries)", 
574                         current_id,
575                         context.m_namespace_map.get(), 
576                         (int)context.m_namespace_map->size());
577         
578         NamespaceDecl *clang_namespace_decl = AddNamespace(context, context.m_namespace_map);
579         
580         if (clang_namespace_decl)
581             clang_namespace_decl->setHasExternalVisibleStorage();
582     }
583 }
584
585 void 
586 ClangASTSource::FindExternalVisibleDecls (NameSearchContext &context, 
587                                           lldb::ModuleSP module_sp,
588                                           ClangNamespaceDecl &namespace_decl,
589                                           unsigned int current_id)
590 {
591     assert (m_ast_context);
592     
593     Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS));
594     
595     SymbolContextList sc_list;
596     
597     const ConstString name(context.m_decl_name.getAsString().c_str());
598     
599     const char *name_unique_cstr = name.GetCString();
600     
601     static ConstString id_name("id");
602     static ConstString Class_name("Class");
603     
604     if (name == id_name || name == Class_name)
605         return;
606     
607     if (name_unique_cstr == NULL)
608         return;
609     
610     // The ClangASTSource is not responsible for finding $-names.
611     if (name_unique_cstr[0] == '$')
612         return;
613     
614     if (module_sp && namespace_decl)
615     {
616         ClangNamespaceDecl found_namespace_decl;
617         
618         SymbolVendor *symbol_vendor = module_sp->GetSymbolVendor();
619         
620         if (symbol_vendor)
621         {
622             SymbolContext null_sc;
623             
624             found_namespace_decl = symbol_vendor->FindNamespace(null_sc, name, &namespace_decl);
625             
626             if (found_namespace_decl)
627             {
628                 context.m_namespace_map->push_back(std::pair<lldb::ModuleSP, ClangNamespaceDecl>(module_sp, found_namespace_decl));
629                 
630                 if (log)
631                     log->Printf("  CAS::FEVD[%u] Found namespace %s in module %s",
632                                 current_id,
633                                 name.GetCString(), 
634                                 module_sp->GetFileSpec().GetFilename().GetCString());
635             }
636         }
637     }
638     else 
639     {
640         const ModuleList &target_images = m_target->GetImages();
641         Mutex::Locker modules_locker (target_images.GetMutex());
642         
643         for (size_t i = 0, e = target_images.GetSize(); i < e; ++i)
644         {
645             lldb::ModuleSP image = target_images.GetModuleAtIndexUnlocked(i);
646             
647             if (!image)
648                 continue;
649             
650             ClangNamespaceDecl found_namespace_decl;
651             
652             SymbolVendor *symbol_vendor = image->GetSymbolVendor();
653             
654             if (!symbol_vendor)
655                 continue;
656             
657             SymbolContext null_sc;
658             
659             found_namespace_decl = symbol_vendor->FindNamespace(null_sc, name, &namespace_decl);
660             
661             if (found_namespace_decl)
662             {
663                 context.m_namespace_map->push_back(std::pair<lldb::ModuleSP, ClangNamespaceDecl>(image, found_namespace_decl));
664                 
665                 if (log)
666                     log->Printf("  CAS::FEVD[%u] Found namespace %s in module %s",
667                                 current_id,
668                                 name.GetCString(), 
669                                 image->GetFileSpec().GetFilename().GetCString());
670             }
671         }
672     }
673     
674     do 
675     {
676         TypeList types;
677         SymbolContext null_sc;
678         const bool exact_match = false;
679       
680         if (module_sp && namespace_decl)
681             module_sp->FindTypesInNamespace(null_sc, name, &namespace_decl, 1, types);
682         else 
683             m_target->GetImages().FindTypes(null_sc, name, exact_match, 1, types);
684         
685         if (types.GetSize())
686         {
687             lldb::TypeSP type_sp = types.GetTypeAtIndex(0);
688             
689             if (log)
690             {
691                 const char *name_string = type_sp->GetName().GetCString();
692                 
693                 log->Printf("  CAS::FEVD[%u] Matching type found for \"%s\": %s", 
694                             current_id, 
695                             name.GetCString(), 
696                             (name_string ? name_string : "<anonymous>"));
697             }
698                         
699             ClangASTType full_type = type_sp->GetClangFullType();
700
701             ClangASTType copied_clang_type (GuardedCopyType(full_type));
702                 
703             if (!copied_clang_type)
704             {                
705                 if (log)
706                     log->Printf("  CAS::FEVD[%u] - Couldn't export a type",
707                                 current_id);
708                     
709                 break;
710             }
711                 
712             context.AddTypeDecl(copied_clang_type);
713         }
714         else
715         {
716             do
717             {
718                 // Couldn't find any types elsewhere.  Try the Objective-C runtime if one exists.
719                 
720                 lldb::ProcessSP process(m_target->GetProcessSP());
721                 
722                 if (!process)
723                     break;
724                 
725                 ObjCLanguageRuntime *language_runtime(process->GetObjCLanguageRuntime());
726                 
727                 if (!language_runtime)
728                     break;
729                 
730                 TypeVendor *type_vendor = language_runtime->GetTypeVendor();
731                 
732                 if (!type_vendor)
733                     break;
734                 
735                 bool append = false;
736                 uint32_t max_matches = 1;
737                 std::vector <ClangASTType> types;
738                 
739                 if (!type_vendor->FindTypes(name,
740                                             append,
741                                             max_matches,
742                                             types))
743                     break;
744                 
745                 if (log)
746                 {                    
747                     log->Printf("  CAS::FEVD[%u] Matching type found for \"%s\" in the runtime",
748                                 current_id,
749                                 name.GetCString());
750                 }
751                 
752                 ClangASTType copied_clang_type (GuardedCopyType(types[0]));
753                 
754                 if (!copied_clang_type)
755                 {
756                     if (log)
757                         log->Printf("  CAS::FEVD[%u] - Couldn't export a type from the runtime",
758                                     current_id);
759                     
760                     break;
761                 }
762                 
763                 context.AddTypeDecl(copied_clang_type);
764             }
765             while(0);
766         }
767         
768     } while(0);
769 }
770
771 template <class D> class TaggedASTDecl {
772 public:
773     TaggedASTDecl() : decl(NULL) { }
774     TaggedASTDecl(D *_decl) : decl(_decl) { }
775     bool IsValid() const { return (decl != NULL); }
776     bool IsInvalid() const { return !IsValid(); }
777     D *operator->() const { return decl; }
778     D *decl;
779 };
780
781 template <class D2, template <class D> class TD, class D1> 
782 TD<D2>
783 DynCast(TD<D1> source)
784 {
785     return TD<D2> (dyn_cast<D2>(source.decl));
786 }
787
788 template <class D = Decl> class DeclFromParser;
789 template <class D = Decl> class DeclFromUser;
790
791 template <class D> class DeclFromParser : public TaggedASTDecl<D> { 
792 public:
793     DeclFromParser() : TaggedASTDecl<D>() { }
794     DeclFromParser(D *_decl) : TaggedASTDecl<D>(_decl) { }
795     
796     DeclFromUser<D> GetOrigin(ClangASTImporter *importer);
797 };
798
799 template <class D> class DeclFromUser : public TaggedASTDecl<D> { 
800 public:
801     DeclFromUser() : TaggedASTDecl<D>() { }
802     DeclFromUser(D *_decl) : TaggedASTDecl<D>(_decl) { }
803     
804     DeclFromParser<D> Import(ClangASTImporter *importer, ASTContext &dest_ctx);
805 };
806
807 template <class D>
808 DeclFromUser<D>
809 DeclFromParser<D>::GetOrigin(ClangASTImporter *importer)
810 {
811     DeclFromUser <> origin_decl;
812     importer->ResolveDeclOrigin(this->decl, &origin_decl.decl, NULL);
813     if (origin_decl.IsInvalid())
814         return DeclFromUser<D>();
815     return DeclFromUser<D>(dyn_cast<D>(origin_decl.decl));
816 }
817
818 template <class D>
819 DeclFromParser<D>
820 DeclFromUser<D>::Import(ClangASTImporter *importer, ASTContext &dest_ctx)
821 {
822     DeclFromParser <> parser_generic_decl(importer->CopyDecl(&dest_ctx, &this->decl->getASTContext(), this->decl));
823     if (parser_generic_decl.IsInvalid())
824         return DeclFromParser<D>();
825     return DeclFromParser<D>(dyn_cast<D>(parser_generic_decl.decl));
826 }
827
828 static bool
829 FindObjCMethodDeclsWithOrigin (unsigned int current_id,
830                                NameSearchContext &context,
831                                ObjCInterfaceDecl *original_interface_decl,
832                                clang::ASTContext *ast_context,
833                                ClangASTImporter *ast_importer,
834                                const char *log_info)
835 {
836     const DeclarationName &decl_name(context.m_decl_name);
837     clang::ASTContext *original_ctx = &original_interface_decl->getASTContext();
838
839     Selector original_selector;
840     
841     if (decl_name.isObjCZeroArgSelector())
842     {
843         IdentifierInfo *ident = &original_ctx->Idents.get(decl_name.getAsString());
844         original_selector = original_ctx->Selectors.getSelector(0, &ident);
845     }
846     else if (decl_name.isObjCOneArgSelector())
847     {
848         const std::string &decl_name_string = decl_name.getAsString();
849         std::string decl_name_string_without_colon(decl_name_string.c_str(), decl_name_string.length() - 1);
850         IdentifierInfo *ident = &original_ctx->Idents.get(decl_name_string_without_colon.c_str());
851         original_selector = original_ctx->Selectors.getSelector(1, &ident);
852     }
853     else
854     {
855         SmallVector<IdentifierInfo *, 4> idents;
856         
857         clang::Selector sel = decl_name.getObjCSelector();
858         
859         unsigned num_args = sel.getNumArgs();
860         
861         for (unsigned i = 0;
862              i != num_args;
863              ++i)
864         {
865             idents.push_back(&original_ctx->Idents.get(sel.getNameForSlot(i)));
866         }
867         
868         original_selector = original_ctx->Selectors.getSelector(num_args, idents.data());
869     }
870     
871     DeclarationName original_decl_name(original_selector);
872     
873     ObjCInterfaceDecl::lookup_result result = original_interface_decl->lookup(original_decl_name);
874     
875     if (result.empty())
876         return false;
877     
878     if (!result[0])
879         return false;
880     
881     ObjCMethodDecl *result_method = dyn_cast<ObjCMethodDecl>(result[0]);
882     
883     if (!result_method)
884         return false;
885     
886     Decl *copied_decl = ast_importer->CopyDecl(ast_context, &result_method->getASTContext(), result_method);
887     
888     if (!copied_decl)
889         return false;
890     
891     ObjCMethodDecl *copied_method_decl = dyn_cast<ObjCMethodDecl>(copied_decl);
892     
893     if (!copied_method_decl)
894         return false;
895     
896     Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS));
897     
898     if (log)
899     {
900         ASTDumper dumper((Decl*)copied_method_decl);
901         log->Printf("  CAS::FOMD[%d] found (%s) %s", current_id, log_info, dumper.GetCString());
902     }
903     
904     context.AddNamedDecl(copied_method_decl);
905     
906     return true;
907 }
908
909 void
910 ClangASTSource::FindObjCMethodDecls (NameSearchContext &context)
911 {
912     Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS));
913     
914     static unsigned int invocation_id = 0;
915     unsigned int current_id = invocation_id++;
916     
917     const DeclarationName &decl_name(context.m_decl_name);
918     const DeclContext *decl_ctx(context.m_decl_context);
919     
920     const ObjCInterfaceDecl *interface_decl = dyn_cast<ObjCInterfaceDecl>(decl_ctx);
921     
922     if (!interface_decl)
923         return;
924     
925     do
926     {
927         Decl *original_decl = NULL;
928         ASTContext *original_ctx = NULL;
929         
930         m_ast_importer->ResolveDeclOrigin(interface_decl, &original_decl, &original_ctx);
931         
932         if (!original_decl)
933             break;
934             
935         ObjCInterfaceDecl *original_interface_decl = dyn_cast<ObjCInterfaceDecl>(original_decl);
936         
937         if (FindObjCMethodDeclsWithOrigin(current_id,
938                                           context,
939                                           original_interface_decl,
940                                           m_ast_context,
941                                           m_ast_importer,
942                                           "at origin"))
943             return; // found it, no need to look any further
944     } while (0);
945     
946     StreamString ss;
947         
948     if (decl_name.isObjCZeroArgSelector())
949     {
950         ss.Printf("%s", decl_name.getAsString().c_str());
951     }
952     else if (decl_name.isObjCOneArgSelector())
953     {
954         ss.Printf("%s", decl_name.getAsString().c_str());
955     }
956     else
957     {    
958         clang::Selector sel = decl_name.getObjCSelector();
959         
960         for (unsigned i = 0, e = sel.getNumArgs();
961              i != e;
962              ++i)
963         {
964             llvm::StringRef r = sel.getNameForSlot(i);
965             ss.Printf("%s:", r.str().c_str()); 
966         }
967     }     
968     ss.Flush();
969     
970     ConstString selector_name(ss.GetData());
971     
972     if (log)
973         log->Printf("ClangASTSource::FindObjCMethodDecls[%d] on (ASTContext*)%p for selector [%s %s]",
974                     current_id,
975                     m_ast_context,
976                     interface_decl->getNameAsString().c_str(), 
977                     selector_name.AsCString());
978     SymbolContextList sc_list;
979     
980     const bool include_symbols = false;
981     const bool include_inlines = false;
982     const bool append = false;
983     
984     std::string interface_name = interface_decl->getNameAsString();
985     
986     do
987     {
988         StreamString ms;
989         ms.Printf("-[%s %s]", interface_name.c_str(), selector_name.AsCString());
990         ms.Flush();
991         ConstString instance_method_name(ms.GetData());
992         
993         m_target->GetImages().FindFunctions(instance_method_name, lldb::eFunctionNameTypeFull, include_symbols, include_inlines, append, sc_list);
994         
995         if (sc_list.GetSize())
996             break;
997         
998         ms.Clear();
999         ms.Printf("+[%s %s]", interface_name.c_str(), selector_name.AsCString());
1000         ms.Flush();
1001         ConstString class_method_name(ms.GetData());
1002         
1003         m_target->GetImages().FindFunctions(class_method_name, lldb::eFunctionNameTypeFull, include_symbols, include_inlines, append, sc_list);
1004         
1005         if (sc_list.GetSize())
1006             break;
1007         
1008         // Fall back and check for methods in categories.  If we find methods this way, we need to check that they're actually in
1009         // categories on the desired class.
1010         
1011         SymbolContextList candidate_sc_list;
1012         
1013         m_target->GetImages().FindFunctions(selector_name, lldb::eFunctionNameTypeSelector, include_symbols, include_inlines, append, candidate_sc_list);
1014         
1015         for (uint32_t ci = 0, ce = candidate_sc_list.GetSize();
1016              ci != ce;
1017              ++ci)
1018         {
1019             SymbolContext candidate_sc;
1020             
1021             if (!candidate_sc_list.GetContextAtIndex(ci, candidate_sc))
1022                 continue;
1023             
1024             if (!candidate_sc.function)
1025                 continue;
1026             
1027             const char *candidate_name = candidate_sc.function->GetName().AsCString();
1028             
1029             const char *cursor = candidate_name;
1030             
1031             if (*cursor != '+' && *cursor != '-')
1032                 continue;
1033             
1034             ++cursor;
1035             
1036             if (*cursor != '[')
1037                 continue;
1038             
1039             ++cursor;
1040             
1041             size_t interface_len = interface_name.length();
1042             
1043             if (strncmp(cursor, interface_name.c_str(), interface_len))
1044                 continue;
1045             
1046             cursor += interface_len;
1047             
1048             if (*cursor == ' ' || *cursor == '(')
1049                 sc_list.Append(candidate_sc);
1050         }
1051     }
1052     while (0);
1053     
1054     if (sc_list.GetSize())
1055     {
1056         // We found a good function symbol.  Use that.
1057         
1058         for (uint32_t i = 0, e = sc_list.GetSize();
1059              i != e;
1060              ++i)
1061         {
1062             SymbolContext sc;
1063             
1064             if (!sc_list.GetContextAtIndex(i, sc))
1065                 continue;
1066             
1067             if (!sc.function)
1068                 continue;
1069             
1070             DeclContext *function_ctx = sc.function->GetClangDeclContext();
1071             
1072             if (!function_ctx)
1073                 continue;
1074             
1075             ObjCMethodDecl *method_decl = dyn_cast<ObjCMethodDecl>(function_ctx);
1076             
1077             if (!method_decl)
1078                 continue;
1079             
1080             ObjCInterfaceDecl *found_interface_decl = method_decl->getClassInterface();
1081             
1082             if (!found_interface_decl)
1083                 continue;
1084             
1085             if (found_interface_decl->getName() == interface_decl->getName())
1086             {
1087                 Decl *copied_decl = m_ast_importer->CopyDecl(m_ast_context, &method_decl->getASTContext(), method_decl);
1088                 
1089                 if (!copied_decl)
1090                     continue;
1091                 
1092                 ObjCMethodDecl *copied_method_decl = dyn_cast<ObjCMethodDecl>(copied_decl);
1093                 
1094                 if (!copied_method_decl)
1095                     continue;
1096                 
1097                 if (log)
1098                 {
1099                     ASTDumper dumper((Decl*)copied_method_decl);
1100                     log->Printf("  CAS::FOMD[%d] found (in symbols) %s", current_id, dumper.GetCString());
1101                 }
1102                 
1103                 context.AddNamedDecl(copied_method_decl);
1104             }
1105         }
1106         
1107         return;
1108     }
1109     
1110     // Try the debug information.
1111     
1112     do
1113     {
1114         ObjCInterfaceDecl *complete_interface_decl = GetCompleteObjCInterface(const_cast<ObjCInterfaceDecl*>(interface_decl));
1115         
1116         if (!complete_interface_decl)
1117             break;
1118         
1119         // We found the complete interface.  The runtime never needs to be queried in this scenario.
1120         
1121         DeclFromUser<const ObjCInterfaceDecl> complete_iface_decl(complete_interface_decl);
1122         
1123         if (complete_interface_decl == interface_decl)
1124             break; // already checked this one
1125         
1126         if (log)
1127             log->Printf("CAS::FOPD[%d] trying origin (ObjCInterfaceDecl*)%p/(ASTContext*)%p...",
1128                         current_id,
1129                         complete_interface_decl,
1130                         &complete_iface_decl->getASTContext());
1131         
1132         FindObjCMethodDeclsWithOrigin(current_id,
1133                                       context,
1134                                       complete_interface_decl,
1135                                       m_ast_context,
1136                                       m_ast_importer,
1137                                       "in debug info");
1138         
1139         return;
1140     }
1141     while (0);
1142     
1143     do
1144     {
1145         // Check the runtime only if the debug information didn't have a complete interface.
1146         
1147         lldb::ProcessSP process(m_target->GetProcessSP());
1148         
1149         if (!process)
1150             break;
1151         
1152         ObjCLanguageRuntime *language_runtime(process->GetObjCLanguageRuntime());
1153         
1154         if (!language_runtime)
1155             break;
1156         
1157         TypeVendor *type_vendor = language_runtime->GetTypeVendor();
1158         
1159         if (!type_vendor)
1160             break;
1161         
1162         ConstString interface_name(interface_decl->getNameAsString().c_str());
1163         bool append = false;
1164         uint32_t max_matches = 1;
1165         std::vector <ClangASTType> types;
1166         
1167         if (!type_vendor->FindTypes(interface_name,
1168                                     append,
1169                                     max_matches,
1170                                     types))
1171             break;
1172         
1173         const clang::Type *runtime_clang_type = QualType::getFromOpaquePtr(types[0].GetOpaqueQualType()).getTypePtr();
1174         
1175         const ObjCInterfaceType *runtime_interface_type = dyn_cast<ObjCInterfaceType>(runtime_clang_type);
1176         
1177         if (!runtime_interface_type)
1178             break;
1179         
1180         ObjCInterfaceDecl *runtime_interface_decl = runtime_interface_type->getDecl();
1181         
1182         FindObjCMethodDeclsWithOrigin(current_id,
1183                                       context,
1184                                       runtime_interface_decl,
1185                                       m_ast_context,
1186                                       m_ast_importer,
1187                                       "in runtime");
1188     }
1189     while(0);
1190 }
1191
1192 static bool
1193 FindObjCPropertyAndIvarDeclsWithOrigin (unsigned int current_id, 
1194                                         NameSearchContext &context,
1195                                         clang::ASTContext &ast_context,
1196                                         ClangASTImporter *ast_importer,
1197                                         DeclFromUser<const ObjCInterfaceDecl> &origin_iface_decl)
1198 {
1199     Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS));
1200
1201     if (origin_iface_decl.IsInvalid())
1202         return false;
1203     
1204     std::string name_str = context.m_decl_name.getAsString();
1205     StringRef name(name_str.c_str());
1206     IdentifierInfo &name_identifier(origin_iface_decl->getASTContext().Idents.get(name));
1207     
1208     DeclFromUser<ObjCPropertyDecl> origin_property_decl(origin_iface_decl->FindPropertyDeclaration(&name_identifier));
1209     
1210     bool found = false;
1211     
1212     if (origin_property_decl.IsValid())
1213     {
1214         DeclFromParser<ObjCPropertyDecl> parser_property_decl(origin_property_decl.Import(ast_importer, ast_context));
1215         if (parser_property_decl.IsValid())
1216         {
1217             if (log)
1218             {
1219                 ASTDumper dumper((Decl*)parser_property_decl.decl);
1220                 log->Printf("  CAS::FOPD[%d] found %s", current_id, dumper.GetCString());
1221             }
1222             
1223             context.AddNamedDecl(parser_property_decl.decl);
1224             found = true;
1225         }
1226     }
1227     
1228     DeclFromUser<ObjCIvarDecl> origin_ivar_decl(origin_iface_decl->getIvarDecl(&name_identifier));
1229     
1230     if (origin_ivar_decl.IsValid())
1231     {
1232         DeclFromParser<ObjCIvarDecl> parser_ivar_decl(origin_ivar_decl.Import(ast_importer, ast_context));
1233         if (parser_ivar_decl.IsValid())
1234         {
1235             if (log)
1236             {
1237                 ASTDumper dumper((Decl*)parser_ivar_decl.decl);
1238                 log->Printf("  CAS::FOPD[%d] found %s", current_id, dumper.GetCString());
1239             }
1240             
1241             context.AddNamedDecl(parser_ivar_decl.decl);
1242             found = true;
1243         }
1244     }
1245     
1246     return found;
1247 }
1248
1249 void
1250 ClangASTSource::FindObjCPropertyAndIvarDecls (NameSearchContext &context)
1251 {
1252     Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS));
1253
1254     static unsigned int invocation_id = 0;
1255     unsigned int current_id = invocation_id++;
1256     
1257     DeclFromParser<const ObjCInterfaceDecl> parser_iface_decl(cast<ObjCInterfaceDecl>(context.m_decl_context));
1258     DeclFromUser<const ObjCInterfaceDecl> origin_iface_decl(parser_iface_decl.GetOrigin(m_ast_importer));
1259
1260     ConstString class_name(parser_iface_decl->getNameAsString().c_str());
1261     
1262     if (log)
1263         log->Printf("ClangASTSource::FindObjCPropertyAndIvarDecls[%d] on (ASTContext*)%p for '%s.%s'",
1264                     current_id, 
1265                     m_ast_context,
1266                     parser_iface_decl->getNameAsString().c_str(), 
1267                     context.m_decl_name.getAsString().c_str());
1268     
1269     if (FindObjCPropertyAndIvarDeclsWithOrigin(current_id, 
1270                                                context, 
1271                                                *m_ast_context, 
1272                                                m_ast_importer, 
1273                                                origin_iface_decl))
1274         return;
1275     
1276     if (log)
1277         log->Printf("CAS::FOPD[%d] couldn't find the property on origin (ObjCInterfaceDecl*)%p/(ASTContext*)%p, searching elsewhere...",
1278                     current_id,
1279                     origin_iface_decl.decl, 
1280                     &origin_iface_decl->getASTContext());
1281     
1282     SymbolContext null_sc;
1283     TypeList type_list;
1284     
1285     do
1286     {
1287         ObjCInterfaceDecl *complete_interface_decl = GetCompleteObjCInterface(const_cast<ObjCInterfaceDecl*>(parser_iface_decl.decl));
1288         
1289         if (!complete_interface_decl)
1290             break;
1291         
1292         // We found the complete interface.  The runtime never needs to be queried in this scenario.
1293         
1294         DeclFromUser<const ObjCInterfaceDecl> complete_iface_decl(complete_interface_decl);
1295         
1296         if (complete_iface_decl.decl == origin_iface_decl.decl)
1297             break; // already checked this one
1298         
1299         if (log)
1300             log->Printf("CAS::FOPD[%d] trying origin (ObjCInterfaceDecl*)%p/(ASTContext*)%p...",
1301                         current_id,
1302                         complete_iface_decl.decl, 
1303                         &complete_iface_decl->getASTContext());
1304         
1305         FindObjCPropertyAndIvarDeclsWithOrigin(current_id, 
1306                                                context, 
1307                                                *m_ast_context, 
1308                                                m_ast_importer, 
1309                                                complete_iface_decl);
1310         
1311         return;
1312     }
1313     while(0);
1314     
1315     do
1316     {
1317         // Check the runtime only if the debug information didn't have a complete interface.
1318         
1319         lldb::ProcessSP process(m_target->GetProcessSP());
1320         
1321         if (!process)
1322             return;
1323         
1324         ObjCLanguageRuntime *language_runtime(process->GetObjCLanguageRuntime());
1325         
1326         if (!language_runtime)
1327             return;
1328         
1329         TypeVendor *type_vendor = language_runtime->GetTypeVendor();
1330         
1331         if (!type_vendor)
1332             break;
1333         
1334         bool append = false;
1335         uint32_t max_matches = 1;
1336         std::vector <ClangASTType> types;
1337         
1338         if (!type_vendor->FindTypes(class_name,
1339                                     append,
1340                                     max_matches,
1341                                     types))
1342             break;
1343         
1344         const clang::Type *runtime_clang_type = QualType::getFromOpaquePtr(types[0].GetOpaqueQualType()).getTypePtr();
1345
1346         const ObjCInterfaceType *runtime_interface_type = dyn_cast<ObjCInterfaceType>(runtime_clang_type);
1347         
1348         if (!runtime_interface_type)
1349             break;
1350         
1351         DeclFromUser<const ObjCInterfaceDecl> runtime_iface_decl(runtime_interface_type->getDecl());
1352         
1353         if (log)
1354             log->Printf("CAS::FOPD[%d] trying runtime (ObjCInterfaceDecl*)%p/(ASTContext*)%p...",
1355                         current_id,
1356                         runtime_iface_decl.decl,
1357                         &runtime_iface_decl->getASTContext());
1358         
1359         if (FindObjCPropertyAndIvarDeclsWithOrigin(current_id,
1360                                                    context,
1361                                                    *m_ast_context,
1362                                                    m_ast_importer,
1363                                                    runtime_iface_decl))
1364             return;
1365     }
1366     while(0);
1367 }
1368
1369 typedef llvm::DenseMap <const FieldDecl *, uint64_t> FieldOffsetMap;
1370 typedef llvm::DenseMap <const CXXRecordDecl *, CharUnits> BaseOffsetMap;
1371
1372 template <class D, class O>
1373 static bool
1374 ImportOffsetMap (llvm::DenseMap <const D*, O> &destination_map, 
1375                  llvm::DenseMap <const D*, O> &source_map,
1376                  ClangASTImporter *importer,
1377                  ASTContext &dest_ctx)
1378 {
1379     typedef llvm::DenseMap <const D*, O> MapType;
1380     
1381     for (typename MapType::iterator fi = source_map.begin(), fe = source_map.end();
1382          fi != fe;
1383          ++fi)
1384     {
1385         DeclFromUser <D> user_decl(const_cast<D*>(fi->first));
1386         DeclFromParser <D> parser_decl(user_decl.Import(importer, dest_ctx));
1387         if (parser_decl.IsInvalid())
1388             return false;
1389         destination_map.insert(std::pair<const D *, O>(parser_decl.decl, fi->second));
1390     }
1391     
1392     return true;
1393 }
1394
1395 template <bool IsVirtual> bool ExtractBaseOffsets (const ASTRecordLayout &record_layout,
1396                                                    DeclFromUser<const CXXRecordDecl> &record,
1397                                                    BaseOffsetMap &base_offsets)
1398 {
1399     for (CXXRecordDecl::base_class_const_iterator 
1400             bi = (IsVirtual ? record->vbases_begin() : record->bases_begin()), 
1401             be = (IsVirtual ? record->vbases_end() : record->bases_end());
1402          bi != be;
1403          ++bi)
1404     {
1405         if (!IsVirtual && bi->isVirtual())
1406             continue;
1407         
1408         const clang::Type *origin_base_type = bi->getType().getTypePtr();
1409         const clang::RecordType *origin_base_record_type = origin_base_type->getAs<RecordType>();
1410         
1411         if (!origin_base_record_type)
1412             return false;
1413         
1414         DeclFromUser <RecordDecl> origin_base_record(origin_base_record_type->getDecl());
1415         
1416         if (origin_base_record.IsInvalid())
1417             return false;
1418         
1419         DeclFromUser <CXXRecordDecl> origin_base_cxx_record(DynCast<CXXRecordDecl>(origin_base_record));
1420         
1421         if (origin_base_cxx_record.IsInvalid())
1422             return false;
1423         
1424         CharUnits base_offset;
1425         
1426         if (IsVirtual)
1427             base_offset = record_layout.getVBaseClassOffset(origin_base_cxx_record.decl);
1428         else
1429             base_offset = record_layout.getBaseClassOffset(origin_base_cxx_record.decl);
1430         
1431         base_offsets.insert(std::pair<const CXXRecordDecl *, CharUnits>(origin_base_cxx_record.decl, base_offset));
1432     }
1433     
1434     return true;
1435 }
1436                          
1437 bool 
1438 ClangASTSource::layoutRecordType(const RecordDecl *record,
1439                                  uint64_t &size, 
1440                                  uint64_t &alignment,
1441                                  FieldOffsetMap &field_offsets,
1442                                  BaseOffsetMap &base_offsets,
1443                                  BaseOffsetMap &virtual_base_offsets)
1444 {
1445     ClangASTMetrics::RegisterRecordLayout();
1446     
1447     static unsigned int invocation_id = 0;
1448     unsigned int current_id = invocation_id++;
1449     
1450     Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS));
1451     
1452     if (log)
1453     {
1454         log->Printf("LayoutRecordType[%u] on (ASTContext*)%p for (RecordDecl*)%p [name = '%s']",
1455                     current_id,
1456                     m_ast_context,
1457                     record,
1458                     record->getNameAsString().c_str());
1459     }
1460     
1461     
1462     DeclFromParser <const RecordDecl> parser_record(record);
1463     DeclFromUser <const RecordDecl> origin_record(parser_record.GetOrigin(m_ast_importer));
1464     
1465     if (origin_record.IsInvalid())
1466         return false;
1467         
1468     FieldOffsetMap origin_field_offsets;
1469     BaseOffsetMap origin_base_offsets;
1470     BaseOffsetMap origin_virtual_base_offsets;
1471     
1472     ClangASTContext::GetCompleteDecl(&origin_record->getASTContext(), const_cast<RecordDecl*>(origin_record.decl));
1473     
1474     if (!origin_record.decl->getDefinition())
1475         return false;
1476     
1477     const ASTRecordLayout &record_layout(origin_record->getASTContext().getASTRecordLayout(origin_record.decl));
1478     
1479     int field_idx = 0, field_count = record_layout.getFieldCount();
1480     
1481     for (RecordDecl::field_iterator fi = origin_record->field_begin(), fe = origin_record->field_end();
1482          fi != fe;
1483          ++fi)
1484     {
1485         if (field_idx >= field_count)
1486             return false; // Layout didn't go well.  Bail out.
1487         
1488         uint64_t field_offset = record_layout.getFieldOffset(field_idx);
1489         
1490         origin_field_offsets.insert(std::pair<const FieldDecl *, uint64_t>(*fi, field_offset));
1491         
1492         field_idx++;
1493     }
1494         
1495     ASTContext &parser_ast_context(record->getASTContext());
1496
1497     DeclFromUser <const CXXRecordDecl> origin_cxx_record(DynCast<const CXXRecordDecl>(origin_record));
1498
1499     if (origin_cxx_record.IsValid())
1500     {
1501         if (!ExtractBaseOffsets<false>(record_layout, origin_cxx_record, origin_base_offsets) ||
1502             !ExtractBaseOffsets<true>(record_layout, origin_cxx_record, origin_virtual_base_offsets))
1503             return false;
1504     }
1505
1506     if (!ImportOffsetMap(field_offsets, origin_field_offsets, m_ast_importer, parser_ast_context) ||
1507         !ImportOffsetMap(base_offsets, origin_base_offsets, m_ast_importer, parser_ast_context) ||
1508         !ImportOffsetMap(virtual_base_offsets, origin_virtual_base_offsets, m_ast_importer, parser_ast_context))
1509         return false;
1510     
1511     size = record_layout.getSize().getQuantity() * m_ast_context->getCharWidth();
1512     alignment = record_layout.getAlignment().getQuantity() * m_ast_context->getCharWidth();
1513     
1514     if (log)
1515     {
1516         log->Printf("LRT[%u] returned:", current_id);
1517         log->Printf("LRT[%u]   Original = (RecordDecl*)%p", current_id, origin_record.decl);
1518         log->Printf("LRT[%u]   Size = %" PRId64, current_id, size);
1519         log->Printf("LRT[%u]   Alignment = %" PRId64, current_id, alignment);
1520         log->Printf("LRT[%u]   Fields:", current_id);
1521         for (RecordDecl::field_iterator fi = record->field_begin(), fe = record->field_end();
1522              fi != fe;
1523              ++fi)
1524         {
1525             log->Printf("LRT[%u]     (FieldDecl*)%p, Name = '%s', Offset = %" PRId64 " bits",
1526                         current_id,
1527                         *fi,
1528                         fi->getNameAsString().c_str(),
1529                         field_offsets[*fi]);
1530         }
1531         DeclFromParser <const CXXRecordDecl> parser_cxx_record = DynCast<const CXXRecordDecl>(parser_record);
1532         if (parser_cxx_record.IsValid())
1533         {
1534             log->Printf("LRT[%u]   Bases:", current_id);
1535             for (CXXRecordDecl::base_class_const_iterator bi = parser_cxx_record->bases_begin(), be = parser_cxx_record->bases_end();
1536                  bi != be;
1537                  ++bi)
1538             {
1539                 bool is_virtual = bi->isVirtual();
1540                 
1541                 QualType base_type = bi->getType();
1542                 const RecordType *base_record_type = base_type->getAs<RecordType>();
1543                 DeclFromParser <RecordDecl> base_record(base_record_type->getDecl());
1544                 DeclFromParser <CXXRecordDecl> base_cxx_record = DynCast<CXXRecordDecl>(base_record);
1545                 
1546                 log->Printf("LRT[%u]     %s(CXXRecordDecl*)%p, Name = '%s', Offset = %" PRId64 " chars",
1547                             current_id,
1548                             (is_virtual ? "Virtual " : ""),
1549                             base_cxx_record.decl,
1550                             base_cxx_record.decl->getNameAsString().c_str(),
1551                             (is_virtual ? virtual_base_offsets[base_cxx_record.decl].getQuantity() :
1552                                           base_offsets[base_cxx_record.decl].getQuantity()));
1553             }
1554         }
1555         else
1556         {
1557             log->Printf("LRD[%u]   Not a CXXRecord, so no bases", current_id);
1558         }
1559     }
1560     
1561     return true;
1562 }
1563
1564 void 
1565 ClangASTSource::CompleteNamespaceMap (ClangASTImporter::NamespaceMapSP &namespace_map,
1566                                       const ConstString &name,
1567                                       ClangASTImporter::NamespaceMapSP &parent_map) const
1568 {
1569     static unsigned int invocation_id = 0;
1570     unsigned int current_id = invocation_id++;
1571     
1572     Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS));
1573     
1574     if (log)
1575     {
1576         if (parent_map && parent_map->size())
1577             log->Printf("CompleteNamespaceMap[%u] on (ASTContext*)%p Searching for namespace %s in namespace %s",
1578                         current_id,
1579                         m_ast_context,
1580                         name.GetCString(),
1581                         parent_map->begin()->second.GetNamespaceDecl()->getDeclName().getAsString().c_str());
1582         else
1583             log->Printf("CompleteNamespaceMap[%u] on (ASTContext*)%p Searching for namespace %s",
1584                         current_id,
1585                         m_ast_context,
1586                         name.GetCString());
1587     }
1588     
1589     
1590     if (parent_map)
1591     {
1592         for (ClangASTImporter::NamespaceMap::iterator i = parent_map->begin(), e = parent_map->end();
1593              i != e;
1594              ++i)
1595         {
1596             ClangNamespaceDecl found_namespace_decl;
1597             
1598             lldb::ModuleSP module_sp = i->first;
1599             ClangNamespaceDecl module_parent_namespace_decl = i->second;
1600             
1601             SymbolVendor *symbol_vendor = module_sp->GetSymbolVendor();
1602             
1603             if (!symbol_vendor)
1604                 continue;
1605             
1606             SymbolContext null_sc;
1607             
1608             found_namespace_decl = symbol_vendor->FindNamespace(null_sc, name, &module_parent_namespace_decl);
1609             
1610             if (!found_namespace_decl)
1611                 continue;
1612             
1613             namespace_map->push_back(std::pair<lldb::ModuleSP, ClangNamespaceDecl>(module_sp, found_namespace_decl));
1614             
1615             if (log)
1616                 log->Printf("  CMN[%u] Found namespace %s in module %s",
1617                             current_id,
1618                             name.GetCString(), 
1619                             module_sp->GetFileSpec().GetFilename().GetCString());
1620         }
1621     }
1622     else
1623     {
1624         const ModuleList &target_images = m_target->GetImages();
1625         Mutex::Locker modules_locker(target_images.GetMutex());
1626         
1627         ClangNamespaceDecl null_namespace_decl;
1628         
1629         for (size_t i = 0, e = target_images.GetSize(); i < e; ++i)
1630         {
1631             lldb::ModuleSP image = target_images.GetModuleAtIndexUnlocked(i);
1632             
1633             if (!image)
1634                 continue;
1635             
1636             ClangNamespaceDecl found_namespace_decl;
1637             
1638             SymbolVendor *symbol_vendor = image->GetSymbolVendor();
1639             
1640             if (!symbol_vendor)
1641                 continue;
1642             
1643             SymbolContext null_sc;
1644             
1645             found_namespace_decl = symbol_vendor->FindNamespace(null_sc, name, &null_namespace_decl);
1646             
1647             if (!found_namespace_decl)
1648                 continue;
1649             
1650             namespace_map->push_back(std::pair<lldb::ModuleSP, ClangNamespaceDecl>(image, found_namespace_decl));
1651             
1652             if (log)
1653                 log->Printf("  CMN[%u] Found namespace %s in module %s",
1654                             current_id,
1655                             name.GetCString(), 
1656                             image->GetFileSpec().GetFilename().GetCString());
1657         }
1658     }
1659 }
1660
1661 NamespaceDecl *
1662 ClangASTSource::AddNamespace (NameSearchContext &context, ClangASTImporter::NamespaceMapSP &namespace_decls)
1663 {
1664     if (!namespace_decls)
1665         return NULL;
1666     
1667     const ClangNamespaceDecl &namespace_decl = namespace_decls->begin()->second;
1668     
1669     Decl *copied_decl = m_ast_importer->CopyDecl(m_ast_context, namespace_decl.GetASTContext(), namespace_decl.GetNamespaceDecl());
1670     
1671     if (!copied_decl)
1672         return NULL;
1673         
1674     NamespaceDecl *copied_namespace_decl = dyn_cast<NamespaceDecl>(copied_decl);
1675     
1676     if (!copied_namespace_decl)
1677         return NULL;
1678     
1679     context.m_decls.push_back(copied_namespace_decl);
1680     
1681     m_ast_importer->RegisterNamespaceMap(copied_namespace_decl, namespace_decls);
1682     
1683     return dyn_cast<NamespaceDecl>(copied_decl);
1684 }
1685
1686 ClangASTType
1687 ClangASTSource::GuardedCopyType (const ClangASTType &src_type)
1688 {
1689     ClangASTMetrics::RegisterLLDBImport();
1690     
1691     SetImportInProgress(true);
1692     
1693     QualType copied_qual_type = m_ast_importer->CopyType (m_ast_context, src_type.GetASTContext(), src_type.GetQualType());
1694     
1695     SetImportInProgress(false);
1696     
1697     if (copied_qual_type.getAsOpaquePtr() && copied_qual_type->getCanonicalTypeInternal().isNull())
1698         // this shouldn't happen, but we're hardening because the AST importer seems to be generating bad types
1699         // on occasion.
1700         return ClangASTType();
1701     
1702     return ClangASTType(m_ast_context, copied_qual_type);
1703 }
1704
1705 clang::NamedDecl *
1706 NameSearchContext::AddVarDecl(const ClangASTType &type)
1707 {
1708     assert (type && "Type for variable must be valid!");
1709
1710     if (!type.IsValid())
1711         return NULL;
1712     
1713     IdentifierInfo *ii = m_decl_name.getAsIdentifierInfo();
1714     
1715     clang::ASTContext *ast = type.GetASTContext();
1716
1717     clang::NamedDecl *Decl = VarDecl::Create(*ast,
1718                                              const_cast<DeclContext*>(m_decl_context), 
1719                                              SourceLocation(), 
1720                                              SourceLocation(),
1721                                              ii, 
1722                                              type.GetQualType(),
1723                                              0, 
1724                                              SC_Static);
1725     m_decls.push_back(Decl);
1726     
1727     return Decl;
1728 }
1729
1730 clang::NamedDecl *
1731 NameSearchContext::AddFunDecl (const ClangASTType &type) 
1732 {
1733     assert (type && "Type for variable must be valid!");
1734     
1735     if (!type.IsValid())
1736         return NULL;
1737
1738     if (m_function_types.count(type))
1739         return NULL;
1740     
1741     m_function_types.insert(type);
1742     
1743     QualType qual_type (type.GetQualType());
1744     
1745     clang::ASTContext *ast = type.GetASTContext();
1746
1747     const bool isInlineSpecified = false;
1748     const bool hasWrittenPrototype = true;
1749     const bool isConstexprSpecified = false;
1750
1751     clang::FunctionDecl *func_decl = FunctionDecl::Create (*ast,
1752                                                            const_cast<DeclContext*>(m_decl_context),
1753                                                            SourceLocation(),
1754                                                            SourceLocation(),
1755                                                            m_decl_name.getAsIdentifierInfo(),
1756                                                            qual_type,
1757                                                            NULL,
1758                                                            SC_Static,
1759                                                            isInlineSpecified,
1760                                                            hasWrittenPrototype,
1761                                                            isConstexprSpecified);
1762
1763     // We have to do more than just synthesize the FunctionDecl.  We have to
1764     // synthesize ParmVarDecls for all of the FunctionDecl's arguments.  To do
1765     // this, we raid the function's FunctionProtoType for types.
1766     
1767     const FunctionProtoType *func_proto_type = qual_type.getTypePtr()->getAs<FunctionProtoType>();
1768     
1769     if (func_proto_type)
1770     {        
1771         unsigned NumArgs = func_proto_type->getNumArgs();
1772         unsigned ArgIndex;
1773         
1774         SmallVector<ParmVarDecl *, 5> parm_var_decls;
1775                 
1776         for (ArgIndex = 0; ArgIndex < NumArgs; ++ArgIndex)
1777         {
1778             QualType arg_qual_type (func_proto_type->getArgType(ArgIndex));
1779             
1780             parm_var_decls.push_back(ParmVarDecl::Create (*ast,
1781                                                           const_cast<DeclContext*>(m_decl_context),
1782                                                           SourceLocation(),
1783                                                           SourceLocation(),
1784                                                           NULL,
1785                                                           arg_qual_type,
1786                                                           NULL,
1787                                                           SC_Static,
1788                                                           NULL));
1789         }
1790         
1791         func_decl->setParams(ArrayRef<ParmVarDecl*>(parm_var_decls));
1792     }
1793     else
1794     {
1795         Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS));
1796
1797         if (log)
1798             log->Printf("Function type wasn't a FunctionProtoType");
1799     }
1800     
1801     m_decls.push_back(func_decl);
1802     
1803     return func_decl;
1804 }
1805
1806 clang::NamedDecl *
1807 NameSearchContext::AddGenericFunDecl()
1808 {
1809     FunctionProtoType::ExtProtoInfo proto_info;
1810     
1811     proto_info.Variadic = true;
1812     
1813     QualType generic_function_type(m_ast_source.m_ast_context->getFunctionType (m_ast_source.m_ast_context->UnknownAnyTy,    // result
1814                                                                                 ArrayRef<QualType>(),                                        // argument types
1815                                                                                 proto_info));
1816     
1817     return AddFunDecl(ClangASTType (m_ast_source.m_ast_context, generic_function_type));
1818 }
1819
1820 clang::NamedDecl *
1821 NameSearchContext::AddTypeDecl(const ClangASTType &clang_type)
1822 {
1823     if (clang_type)
1824     {
1825         QualType qual_type = clang_type.GetQualType();
1826
1827         if (const TypedefType *typedef_type = llvm::dyn_cast<TypedefType>(qual_type))
1828         {
1829             TypedefNameDecl *typedef_name_decl = typedef_type->getDecl();
1830             
1831             m_decls.push_back(typedef_name_decl);
1832             
1833             return (NamedDecl*)typedef_name_decl;
1834         }
1835         else if (const TagType *tag_type = qual_type->getAs<TagType>())
1836         {
1837             TagDecl *tag_decl = tag_type->getDecl();
1838             
1839             m_decls.push_back(tag_decl);
1840             
1841             return tag_decl;
1842         }
1843         else if (const ObjCObjectType *objc_object_type = qual_type->getAs<ObjCObjectType>())
1844         {
1845             ObjCInterfaceDecl *interface_decl = objc_object_type->getInterface();
1846             
1847             m_decls.push_back((NamedDecl*)interface_decl);
1848             
1849             return (NamedDecl*)interface_decl;
1850         }
1851     }
1852     return NULL;
1853 }
1854
1855 void 
1856 NameSearchContext::AddLookupResult (clang::DeclContextLookupConstResult result)
1857 {
1858     for (clang::NamedDecl *decl : result)
1859         m_decls.push_back (decl);
1860 }
1861
1862 void
1863 NameSearchContext::AddNamedDecl (clang::NamedDecl *decl)
1864 {
1865     m_decls.push_back (decl);
1866 }