• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 
~ClangASTSource()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
StartTranslationUnit(ASTConsumer * Consumer)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
FindExternalVisibleDeclsByName(const DeclContext * decl_ctx,DeclarationName clang_decl_name)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
CompleteType(TagDecl * tag_decl)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
CompleteType(clang::ObjCInterfaceDecl * interface_decl)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 *
GetCompleteObjCInterface(clang::ObjCInterfaceDecl * interface_decl)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
FindExternalLexicalDecls(const DeclContext * decl_context,bool (* predicate)(Decl::Kind),llvm::SmallVectorImpl<Decl * > & decls)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
FindExternalVisibleDecls(NameSearchContext & context)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
FindExternalVisibleDecls(NameSearchContext & context,lldb::ModuleSP module_sp,ClangNamespaceDecl & namespace_decl,unsigned int current_id)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:
TaggedASTDecl()773     TaggedASTDecl() : decl(NULL) { }
TaggedASTDecl(D * _decl)774     TaggedASTDecl(D *_decl) : decl(_decl) { }
IsValid() const775     bool IsValid() const { return (decl != NULL); }
IsInvalid() const776     bool IsInvalid() const { return !IsValid(); }
operator ->() const777     D *operator->() const { return decl; }
778     D *decl;
779 };
780 
781 template <class D2, template <class D> class TD, class D1>
782 TD<D2>
DynCast(TD<D1> source)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:
DeclFromParser()793     DeclFromParser() : TaggedASTDecl<D>() { }
DeclFromParser(D * _decl)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:
DeclFromUser()801     DeclFromUser() : TaggedASTDecl<D>() { }
DeclFromUser(D * _decl)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>
GetOrigin(ClangASTImporter * importer)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>
Import(ClangASTImporter * importer,ASTContext & dest_ctx)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
FindObjCMethodDeclsWithOrigin(unsigned int current_id,NameSearchContext & context,ObjCInterfaceDecl * original_interface_decl,clang::ASTContext * ast_context,ClangASTImporter * ast_importer,const char * log_info)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
FindObjCMethodDecls(NameSearchContext & context)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
FindObjCPropertyAndIvarDeclsWithOrigin(unsigned int current_id,NameSearchContext & context,clang::ASTContext & ast_context,ClangASTImporter * ast_importer,DeclFromUser<const ObjCInterfaceDecl> & origin_iface_decl)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
FindObjCPropertyAndIvarDecls(NameSearchContext & context)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
ImportOffsetMap(llvm::DenseMap<const D *,O> & destination_map,llvm::DenseMap<const D *,O> & source_map,ClangASTImporter * importer,ASTContext & dest_ctx)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 
ExtractBaseOffsets(const ASTRecordLayout & record_layout,DeclFromUser<const CXXRecordDecl> & record,BaseOffsetMap & base_offsets)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
layoutRecordType(const RecordDecl * record,uint64_t & size,uint64_t & alignment,FieldOffsetMap & field_offsets,BaseOffsetMap & base_offsets,BaseOffsetMap & virtual_base_offsets)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
CompleteNamespaceMap(ClangASTImporter::NamespaceMapSP & namespace_map,const ConstString & name,ClangASTImporter::NamespaceMapSP & parent_map) const1565 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 *
AddNamespace(NameSearchContext & context,ClangASTImporter::NamespaceMapSP & namespace_decls)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
GuardedCopyType(const ClangASTType & src_type)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 *
AddVarDecl(const ClangASTType & type)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 *
AddFunDecl(const ClangASTType & type)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 *
AddGenericFunDecl()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 *
AddTypeDecl(const ClangASTType & clang_type)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
AddLookupResult(clang::DeclContextLookupConstResult result)1856 NameSearchContext::AddLookupResult (clang::DeclContextLookupConstResult result)
1857 {
1858     for (clang::NamedDecl *decl : result)
1859         m_decls.push_back (decl);
1860 }
1861 
1862 void
AddNamedDecl(clang::NamedDecl * decl)1863 NameSearchContext::AddNamedDecl (clang::NamedDecl *decl)
1864 {
1865     m_decls.push_back (decl);
1866 }
1867